umap-project 2.7.3__py3-none-any.whl → 2.8.0a0__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 +32 -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 +22 -2
- 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 +617 -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 +101 -74
- umap/static/umap/js/modules/data/layer.js +157 -137
- 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 +71 -39
- 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/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 +10 -9
- umap/static/umap/js/modules/rendering/template.js +35 -12
- umap/static/umap/js/modules/rendering/ui.js +57 -12
- 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 +5 -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/panel.js +10 -9
- umap/static/umap/js/modules/umap.js +1668 -0
- umap/static/umap/js/modules/urls.js +2 -2
- umap/static/umap/js/modules/utils.js +20 -6
- umap/static/umap/js/umap.controls.js +74 -301
- umap/static/umap/js/umap.core.js +29 -50
- umap/static/umap/js/umap.forms.js +34 -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 +12 -9
- umap/static/umap/locale/en.json +12 -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 +12 -9
- umap/static/umap/locale/fr.json +12 -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 +5 -364
- umap/static/umap/unittests/URLs.js +15 -15
- umap/static/umap/unittests/utils.js +23 -1
- umap/static/umap/vars.css +2 -0
- umap/static/umap/vendors/formbuilder/Leaflet.FormBuilder.js +5 -1
- umap/storage.py +152 -0
- umap/templates/registration/login.html +7 -6
- umap/templates/umap/css.html +3 -0
- umap/templates/umap/js.html +1 -2
- umap/templates/umap/map_init.html +4 -5
- umap/templates/umap/user_dashboard.html +18 -19
- umap/tests/base.py +5 -1
- umap/tests/integration/conftest.py +2 -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 +18 -7
- umap/tests/integration/test_import.py +8 -5
- 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_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_views.py +53 -0
- umap/urls.py +3 -3
- umap/views.py +107 -76
- {umap_project-2.7.3.dist-info → umap_project-2.8.0a0.dist-info}/METADATA +16 -13
- {umap_project-2.7.3.dist-info → umap_project-2.8.0a0.dist-info}/RECORD +276 -262
- 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_project-2.7.3.dist-info → umap_project-2.8.0a0.dist-info}/WHEEL +0 -0
- {umap_project-2.7.3.dist-info → umap_project-2.8.0a0.dist-info}/entry_points.txt +0 -0
- {umap_project-2.7.3.dist-info → umap_project-2.8.0a0.dist-info}/licenses/LICENSE +0 -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.UmapS3",
|
|
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
|
+
)
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import json
|
|
2
2
|
from copy import deepcopy
|
|
3
3
|
from pathlib import Path
|
|
4
|
+
from uuid import uuid4
|
|
4
5
|
|
|
5
6
|
import pytest
|
|
6
7
|
from django.core.files.base import ContentFile
|
|
@@ -105,6 +106,21 @@ def test_gzip_should_be_created_if_accepted(client, datalayer, map, post_data):
|
|
|
105
106
|
assert Path(flat).stat().st_mtime_ns == Path(gzipped).stat().st_mtime_ns
|
|
106
107
|
|
|
107
108
|
|
|
109
|
+
def test_create_datalayer(client, map, post_data):
|
|
110
|
+
uuid = str(uuid4())
|
|
111
|
+
url = reverse("datalayer_create", args=(map.pk, uuid))
|
|
112
|
+
client.login(username=map.owner.username, password="123123")
|
|
113
|
+
response = client.post(url, post_data, follow=True)
|
|
114
|
+
assert response.status_code == 200
|
|
115
|
+
new_datalayer = DataLayer.objects.get(pk=uuid)
|
|
116
|
+
assert new_datalayer.name == "name"
|
|
117
|
+
assert new_datalayer.rank == 0
|
|
118
|
+
# Test response is a json
|
|
119
|
+
data = json.loads(response.content.decode())
|
|
120
|
+
assert "id" in data
|
|
121
|
+
assert data["id"] == uuid
|
|
122
|
+
|
|
123
|
+
|
|
108
124
|
def test_update(client, datalayer, map, post_data):
|
|
109
125
|
url = reverse("datalayer_update", args=(map.pk, datalayer.pk))
|
|
110
126
|
client.login(username=map.owner.username, password="123123")
|
|
@@ -215,7 +231,7 @@ def test_optimistic_concurrency_control_with_empty_version(
|
|
|
215
231
|
def test_versions_should_return_versions(client, datalayer, map, settings):
|
|
216
232
|
map.share_status = Map.PUBLIC
|
|
217
233
|
map.save()
|
|
218
|
-
root = datalayer.
|
|
234
|
+
root = datalayer.geojson.storage._base_path(datalayer)
|
|
219
235
|
datalayer.geojson.storage.save(
|
|
220
236
|
"%s/%s_1440924889.geojson" % (root, datalayer.pk), ContentFile("{}")
|
|
221
237
|
)
|
|
@@ -232,6 +248,7 @@ def test_versions_should_return_versions(client, datalayer, map, settings):
|
|
|
232
248
|
"name": "%s_1440918637.geojson" % datalayer.pk,
|
|
233
249
|
"size": 2,
|
|
234
250
|
"at": "1440918637",
|
|
251
|
+
"ref": "1440918637",
|
|
235
252
|
}
|
|
236
253
|
assert version in versions["versions"]
|
|
237
254
|
|
|
@@ -239,7 +256,7 @@ def test_versions_should_return_versions(client, datalayer, map, settings):
|
|
|
239
256
|
def test_versions_can_return_old_format(client, datalayer, map, settings):
|
|
240
257
|
map.share_status = Map.PUBLIC
|
|
241
258
|
map.save()
|
|
242
|
-
root = datalayer.
|
|
259
|
+
root = datalayer.geojson.storage._base_path(datalayer)
|
|
243
260
|
datalayer.old_id = 123 # old datalayer id (now replaced by uuid)
|
|
244
261
|
datalayer.save()
|
|
245
262
|
|
|
@@ -263,31 +280,32 @@ def test_versions_can_return_old_format(client, datalayer, map, settings):
|
|
|
263
280
|
"name": old_format_version,
|
|
264
281
|
"size": 2,
|
|
265
282
|
"at": "1440918637",
|
|
283
|
+
"ref": "1440918637",
|
|
266
284
|
}
|
|
267
285
|
assert version in versions["versions"]
|
|
268
286
|
|
|
269
|
-
client.get(
|
|
270
|
-
reverse("datalayer_version", args=(map.pk, datalayer.pk, old_format_version))
|
|
271
|
-
)
|
|
287
|
+
client.get(reverse("datalayer_version", args=(map.pk, datalayer.pk, "1440918637")))
|
|
272
288
|
|
|
273
289
|
|
|
274
290
|
def test_version_should_return_one_version_geojson(client, datalayer, map):
|
|
275
291
|
map.share_status = Map.PUBLIC
|
|
276
292
|
map.save()
|
|
277
|
-
root = datalayer.
|
|
293
|
+
root = datalayer.geojson.storage._base_path(datalayer)
|
|
278
294
|
name = "%s_1440924889.geojson" % datalayer.pk
|
|
279
295
|
datalayer.geojson.storage.save("%s/%s" % (root, name), ContentFile("{}"))
|
|
280
|
-
url = reverse("datalayer_version", args=(map.pk, datalayer.pk,
|
|
281
|
-
|
|
296
|
+
url = reverse("datalayer_version", args=(map.pk, datalayer.pk, "1440924889"))
|
|
297
|
+
resp = client.get(url)
|
|
298
|
+
assert resp.status_code == 200
|
|
299
|
+
assert resp.content.decode() == "{}"
|
|
282
300
|
|
|
283
301
|
|
|
284
302
|
def test_version_should_return_403_if_not_allowed(client, datalayer, map):
|
|
285
303
|
map.share_status = Map.PRIVATE
|
|
286
304
|
map.save()
|
|
287
|
-
root = datalayer.
|
|
305
|
+
root = datalayer.geojson.storage._base_path(datalayer)
|
|
288
306
|
name = "%s_1440924889.geojson" % datalayer.pk
|
|
289
307
|
datalayer.geojson.storage.save("%s/%s" % (root, name), ContentFile("{}"))
|
|
290
|
-
url = reverse("datalayer_version", args=(map.pk, datalayer.pk,
|
|
308
|
+
url = reverse("datalayer_version", args=(map.pk, datalayer.pk, "1440924889"))
|
|
291
309
|
assert client.get(url).status_code == 403
|
|
292
310
|
|
|
293
311
|
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
from datetime import datetime, timedelta
|
|
2
|
+
from unittest import mock
|
|
3
|
+
|
|
4
|
+
import pytest
|
|
5
|
+
from django.core.management import call_command
|
|
6
|
+
|
|
7
|
+
from umap.models import Map
|
|
8
|
+
|
|
9
|
+
from .base import MapFactory
|
|
10
|
+
|
|
11
|
+
pytestmark = pytest.mark.django_db
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def test_empty_trash(user):
|
|
15
|
+
recent = MapFactory(owner=user)
|
|
16
|
+
recent_deleted = MapFactory(owner=user)
|
|
17
|
+
recent_deleted.move_to_trash()
|
|
18
|
+
recent_deleted.save()
|
|
19
|
+
with mock.patch("django.utils.timezone.now") as mocked:
|
|
20
|
+
mocked.return_value = datetime.utcnow() - timedelta(days=8)
|
|
21
|
+
old_deleted = MapFactory(owner=user)
|
|
22
|
+
old_deleted.move_to_trash()
|
|
23
|
+
old_deleted.save()
|
|
24
|
+
old = MapFactory(owner=user)
|
|
25
|
+
assert Map.objects.count() == 4
|
|
26
|
+
call_command("empty_trash", "--days=7", "--dry-run")
|
|
27
|
+
assert Map.objects.count() == 4
|
|
28
|
+
call_command("empty_trash", "--days=9")
|
|
29
|
+
assert Map.objects.count() == 4
|
|
30
|
+
call_command("empty_trash", "--days=7")
|
|
31
|
+
assert not Map.objects.filter(pk=old_deleted.pk)
|
|
32
|
+
assert Map.objects.filter(pk=old.pk)
|
|
33
|
+
assert Map.objects.filter(pk=recent.pk)
|
|
34
|
+
assert Map.objects.filter(pk=recent_deleted.pk)
|
umap/tests/test_map.py
CHANGED
|
@@ -2,6 +2,7 @@ import pytest
|
|
|
2
2
|
from django.contrib.auth.models import AnonymousUser
|
|
3
3
|
from django.urls import reverse
|
|
4
4
|
|
|
5
|
+
from umap.forms import DEFAULT_CENTER
|
|
5
6
|
from umap.models import Map
|
|
6
7
|
|
|
7
8
|
from .base import MapFactory
|
|
@@ -160,8 +161,16 @@ def test_can_change_default_edit_status(user, settings):
|
|
|
160
161
|
|
|
161
162
|
|
|
162
163
|
def test_can_change_default_share_status(user, settings):
|
|
164
|
+
map = Map.objects.create(owner=user, center=DEFAULT_CENTER)
|
|
165
|
+
assert map.share_status == Map.DRAFT
|
|
166
|
+
settings.UMAP_DEFAULT_SHARE_STATUS = Map.PUBLIC
|
|
167
|
+
map = Map.objects.create(owner=user, center=DEFAULT_CENTER)
|
|
163
168
|
map = MapFactory(owner=user)
|
|
164
169
|
assert map.share_status == Map.PUBLIC
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
def test_move_to_trash(user, map):
|
|
173
|
+
map.move_to_trash()
|
|
174
|
+
map.save()
|
|
175
|
+
reloaded = Map.objects.get(pk=map.pk)
|
|
176
|
+
assert reloaded.share_status == Map.DELETED
|
umap/tests/test_map_views.py
CHANGED
|
@@ -42,7 +42,7 @@ def test_create(client, user, post_data):
|
|
|
42
42
|
assert created_map.center.y == 48.94415123418794
|
|
43
43
|
assert j["permissions"] == {
|
|
44
44
|
"edit_status": 3,
|
|
45
|
-
"share_status":
|
|
45
|
+
"share_status": 0,
|
|
46
46
|
"owner": {"id": user.pk, "name": "Joe", "url": "/en/user/Joe/"},
|
|
47
47
|
"editors": [],
|
|
48
48
|
}
|
|
@@ -114,8 +114,10 @@ def test_delete(client, map, datalayer):
|
|
|
114
114
|
url, headers={"X-Requested-With": "XMLHttpRequest"}, follow=True
|
|
115
115
|
)
|
|
116
116
|
assert response.status_code == 200
|
|
117
|
-
assert
|
|
118
|
-
assert
|
|
117
|
+
assert Map.objects.filter(pk=map.pk).exists()
|
|
118
|
+
assert DataLayer.objects.filter(pk=datalayer.pk).exists()
|
|
119
|
+
reloaded = Map.objects.get(pk=map.pk)
|
|
120
|
+
assert reloaded.share_status == Map.DELETED
|
|
119
121
|
# Check that user has not been impacted
|
|
120
122
|
assert User.objects.filter(pk=map.owner.pk).exists()
|
|
121
123
|
# Test response is a json
|
|
@@ -241,42 +243,46 @@ def test_map_creation_should_allow_unicode_names(client, map, post_data):
|
|
|
241
243
|
assert created_map.slug == "map"
|
|
242
244
|
|
|
243
245
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
map
|
|
247
|
-
|
|
248
|
-
response = client.get(url)
|
|
249
|
-
assert response.status_code == 200
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
def test_anonymous_can_access_map_with_share_status_open(client, map):
|
|
246
|
+
@pytest.mark.parametrize("share_status", [Map.PUBLIC, Map.OPEN])
|
|
247
|
+
def test_anonymous_can_access_map_with_share_status_accessible(
|
|
248
|
+
client, map, share_status
|
|
249
|
+
):
|
|
253
250
|
url = reverse("map", args=(map.slug, map.pk))
|
|
254
|
-
map.share_status =
|
|
251
|
+
map.share_status = share_status
|
|
255
252
|
map.save()
|
|
256
253
|
response = client.get(url)
|
|
257
254
|
assert response.status_code == 200
|
|
258
255
|
|
|
259
256
|
|
|
260
|
-
|
|
257
|
+
@pytest.mark.parametrize(
|
|
258
|
+
"share_status", [Map.PRIVATE, Map.DRAFT, Map.BLOCKED, Map.DELETED]
|
|
259
|
+
)
|
|
260
|
+
def test_anonymous_cannot_access_map_with_share_status_restricted(
|
|
261
|
+
client, map, share_status
|
|
262
|
+
):
|
|
261
263
|
url = reverse("map", args=(map.slug, map.pk))
|
|
262
|
-
map.share_status =
|
|
264
|
+
map.share_status = share_status
|
|
263
265
|
map.save()
|
|
264
266
|
response = client.get(url)
|
|
265
267
|
assert response.status_code == 403
|
|
266
268
|
|
|
267
269
|
|
|
268
|
-
|
|
270
|
+
@pytest.mark.parametrize("share_status", [Map.PRIVATE, Map.DRAFT])
|
|
271
|
+
def test_owner_can_access_map_with_share_status_restricted(client, map, share_status):
|
|
269
272
|
url = reverse("map", args=(map.slug, map.pk))
|
|
270
|
-
map.share_status =
|
|
273
|
+
map.share_status = share_status
|
|
271
274
|
map.save()
|
|
272
275
|
client.login(username=map.owner.username, password="123123")
|
|
273
276
|
response = client.get(url)
|
|
274
277
|
assert response.status_code == 200
|
|
275
278
|
|
|
276
279
|
|
|
277
|
-
|
|
280
|
+
@pytest.mark.parametrize("share_status", [Map.PRIVATE, Map.DRAFT])
|
|
281
|
+
def test_editors_can_access_map_with_share_status_resricted(
|
|
282
|
+
client, map, user, share_status
|
|
283
|
+
):
|
|
278
284
|
url = reverse("map", args=(map.slug, map.pk))
|
|
279
|
-
map.share_status =
|
|
285
|
+
map.share_status = share_status
|
|
280
286
|
map.editors.add(user)
|
|
281
287
|
map.save()
|
|
282
288
|
client.login(username=user.username, password="123123")
|
|
@@ -284,10 +290,11 @@ def test_editors_can_access_map_with_share_status_private(client, map, user):
|
|
|
284
290
|
assert response.status_code == 200
|
|
285
291
|
|
|
286
292
|
|
|
287
|
-
def
|
|
293
|
+
def test_owner_cannot_access_map_with_share_status_deleted(client, map):
|
|
288
294
|
url = reverse("map", args=(map.slug, map.pk))
|
|
289
|
-
map.share_status = map.
|
|
295
|
+
map.share_status = map.DELETED
|
|
290
296
|
map.save()
|
|
297
|
+
client.login(username=map.owner.username, password="123123")
|
|
291
298
|
response = client.get(url)
|
|
292
299
|
assert response.status_code == 403
|
|
293
300
|
|
|
@@ -401,14 +408,16 @@ def test_anonymous_delete(cookieclient, anonymap):
|
|
|
401
408
|
url, headers={"X-Requested-With": "XMLHttpRequest"}, follow=True
|
|
402
409
|
)
|
|
403
410
|
assert response.status_code == 200
|
|
404
|
-
assert
|
|
411
|
+
assert Map.objects.filter(pk=anonymap.pk).exists()
|
|
412
|
+
reloaded = Map.objects.get(pk=anonymap.pk)
|
|
413
|
+
assert reloaded.share_status == Map.DELETED
|
|
405
414
|
# Test response is a json
|
|
406
415
|
j = json.loads(response.content.decode())
|
|
407
416
|
assert "redirect" in j
|
|
408
417
|
|
|
409
418
|
|
|
410
419
|
@pytest.mark.usefixtures("allow_anonymous")
|
|
411
|
-
def
|
|
420
|
+
def test_no_cookie_cannot_delete(client, anonymap):
|
|
412
421
|
url = reverse("map_delete", args=(anonymap.pk,))
|
|
413
422
|
response = client.post(
|
|
414
423
|
url, headers={"X-Requested-With": "XMLHttpRequest"}, follow=True
|
|
@@ -416,6 +425,24 @@ def test_no_cookie_cant_delete(client, anonymap):
|
|
|
416
425
|
assert response.status_code == 403
|
|
417
426
|
|
|
418
427
|
|
|
428
|
+
@pytest.mark.usefixtures("allow_anonymous")
|
|
429
|
+
def test_no_cookie_cannot_view_anonymous_owned_map_in_draft(client, anonymap):
|
|
430
|
+
anonymap.share_status = Map.DRAFT
|
|
431
|
+
anonymap.save()
|
|
432
|
+
url = reverse("map", kwargs={"map_id": anonymap.pk, "slug": anonymap.slug})
|
|
433
|
+
response = client.get(url)
|
|
434
|
+
assert response.status_code == 403
|
|
435
|
+
|
|
436
|
+
|
|
437
|
+
@pytest.mark.usefixtures("allow_anonymous")
|
|
438
|
+
def test_owner_can_view_anonymous_owned_map_in_draft(cookieclient, anonymap):
|
|
439
|
+
anonymap.share_status = Map.DRAFT
|
|
440
|
+
anonymap.save()
|
|
441
|
+
url = reverse("map", kwargs={"map_id": anonymap.pk, "slug": anonymap.slug})
|
|
442
|
+
response = cookieclient.get(url)
|
|
443
|
+
assert response.status_code == 200
|
|
444
|
+
|
|
445
|
+
|
|
419
446
|
@pytest.mark.usefixtures("allow_anonymous")
|
|
420
447
|
def test_anonymous_edit_url(cookieclient, anonymap):
|
|
421
448
|
url = anonymap.get_anonymous_edit_url()
|
|
@@ -557,16 +584,6 @@ def test_create_readonly(client, user, post_data, settings):
|
|
|
557
584
|
assert response.content == b"Site is readonly for maintenance"
|
|
558
585
|
|
|
559
586
|
|
|
560
|
-
def test_search(client, map):
|
|
561
|
-
# Very basic search, that do not deal with accent nor case.
|
|
562
|
-
# See install.md for how to have a smarter dict + index.
|
|
563
|
-
map.name = "Blé dur"
|
|
564
|
-
map.save()
|
|
565
|
-
url = reverse("search")
|
|
566
|
-
response = client.get(url + "?q=Blé")
|
|
567
|
-
assert "Blé dur" in response.content.decode()
|
|
568
|
-
|
|
569
|
-
|
|
570
587
|
def test_authenticated_user_can_star_map(client, map, user):
|
|
571
588
|
url = reverse("map_star", args=(map.pk,))
|
|
572
589
|
client.login(username=user.username, password="123123")
|
|
@@ -748,7 +765,9 @@ def test_download_multiple_maps_editor(client, map, datalayer):
|
|
|
748
765
|
assert f.infolist()[1].filename == f"umap_backup_test-map_{map.id}.umap"
|
|
749
766
|
|
|
750
767
|
|
|
751
|
-
@pytest.mark.parametrize(
|
|
768
|
+
@pytest.mark.parametrize(
|
|
769
|
+
"share_status", [Map.PRIVATE, Map.BLOCKED, Map.DRAFT, Map.DELETED]
|
|
770
|
+
)
|
|
752
771
|
def test_download_shared_status_map(client, map, datalayer, share_status):
|
|
753
772
|
map.share_status = share_status
|
|
754
773
|
map.save()
|
|
@@ -757,8 +776,9 @@ def test_download_shared_status_map(client, map, datalayer, share_status):
|
|
|
757
776
|
assert response.status_code == 403
|
|
758
777
|
|
|
759
778
|
|
|
760
|
-
|
|
761
|
-
|
|
779
|
+
@pytest.mark.parametrize("share_status", [Map.PRIVATE, Map.DRAFT])
|
|
780
|
+
def test_download_my_map(client, map, datalayer, share_status):
|
|
781
|
+
map.share_status = share_status
|
|
762
782
|
map.save()
|
|
763
783
|
client.login(username=map.owner.username, password="123123")
|
|
764
784
|
url = reverse("map_download", args=(map.pk,))
|
|
@@ -769,7 +789,19 @@ def test_download_my_map(client, map, datalayer):
|
|
|
769
789
|
assert j["type"] == "umap"
|
|
770
790
|
|
|
771
791
|
|
|
772
|
-
@pytest.mark.parametrize("share_status", [Map.
|
|
792
|
+
@pytest.mark.parametrize("share_status", [Map.BLOCKED, Map.DELETED])
|
|
793
|
+
def test_download_my_map_blocked_or_deleted(client, map, datalayer, share_status):
|
|
794
|
+
map.share_status = share_status
|
|
795
|
+
map.save()
|
|
796
|
+
client.login(username=map.owner.username, password="123123")
|
|
797
|
+
url = reverse("map_download", args=(map.pk,))
|
|
798
|
+
response = client.get(url)
|
|
799
|
+
assert response.status_code == 403
|
|
800
|
+
|
|
801
|
+
|
|
802
|
+
@pytest.mark.parametrize(
|
|
803
|
+
"share_status", [Map.PRIVATE, Map.BLOCKED, Map.OPEN, Map.DRAFT]
|
|
804
|
+
)
|
|
773
805
|
def test_oembed_shared_status_map(client, map, datalayer, share_status):
|
|
774
806
|
map.share_status = share_status
|
|
775
807
|
map.save()
|
umap/tests/test_views.py
CHANGED
|
@@ -288,6 +288,28 @@ def test_user_dashboard_display_user_maps(client, map):
|
|
|
288
288
|
assert "Owner only" in body
|
|
289
289
|
|
|
290
290
|
|
|
291
|
+
@pytest.mark.django_db
|
|
292
|
+
def test_user_dashboard_do_not_display_blocked_user_maps(client, map):
|
|
293
|
+
map.share_status = Map.BLOCKED
|
|
294
|
+
map.save()
|
|
295
|
+
client.login(username=map.owner.username, password="123123")
|
|
296
|
+
response = client.get(reverse("user_dashboard"))
|
|
297
|
+
assert response.status_code == 200
|
|
298
|
+
body = response.content.decode()
|
|
299
|
+
assert map.name not in body
|
|
300
|
+
|
|
301
|
+
|
|
302
|
+
@pytest.mark.django_db
|
|
303
|
+
def test_user_dashboard_do_not_display_deleted_user_maps(client, map):
|
|
304
|
+
map.share_status = Map.DELETED
|
|
305
|
+
map.save()
|
|
306
|
+
client.login(username=map.owner.username, password="123123")
|
|
307
|
+
response = client.get(reverse("user_dashboard"))
|
|
308
|
+
assert response.status_code == 200
|
|
309
|
+
body = response.content.decode()
|
|
310
|
+
assert map.name not in body
|
|
311
|
+
|
|
312
|
+
|
|
291
313
|
@pytest.mark.django_db
|
|
292
314
|
def test_user_dashboard_display_user_team_maps(client, map, team, user):
|
|
293
315
|
user.teams.add(team)
|
|
@@ -497,3 +519,34 @@ def test_websocket_token_is_generated_for_editors(client, user, user2, map):
|
|
|
497
519
|
resp = client.get(token_url)
|
|
498
520
|
token = resp.json().get("token")
|
|
499
521
|
assert TimestampSigner().unsign_object(token, max_age=30)
|
|
522
|
+
|
|
523
|
+
|
|
524
|
+
@pytest.mark.django_db
|
|
525
|
+
def test_search(client, map):
|
|
526
|
+
# Very basic search, that do not deal with accent nor case.
|
|
527
|
+
# See install.md for how to have a smarter dict + index.
|
|
528
|
+
map.name = "Blé dur"
|
|
529
|
+
map.save()
|
|
530
|
+
url = reverse("search")
|
|
531
|
+
response = client.get(url + "?q=Blé")
|
|
532
|
+
assert "Blé dur" in response.content.decode()
|
|
533
|
+
|
|
534
|
+
|
|
535
|
+
@pytest.mark.django_db
|
|
536
|
+
def test_cannot_search_blocked_map(client, map):
|
|
537
|
+
map.name = "Blé dur"
|
|
538
|
+
map.share_status = Map.BLOCKED
|
|
539
|
+
map.save()
|
|
540
|
+
url = reverse("search")
|
|
541
|
+
response = client.get(url + "?q=Blé")
|
|
542
|
+
assert "Blé dur" not in response.content.decode()
|
|
543
|
+
|
|
544
|
+
|
|
545
|
+
@pytest.mark.django_db
|
|
546
|
+
def test_cannot_search_deleted_map(client, map):
|
|
547
|
+
map.name = "Blé dur"
|
|
548
|
+
map.share_status = Map.DELETED
|
|
549
|
+
map.save()
|
|
550
|
+
url = reverse("search")
|
|
551
|
+
response = client.get(url + "?q=Blé")
|
|
552
|
+
assert "Blé dur" not in response.content.decode()
|
umap/urls.py
CHANGED
|
@@ -87,7 +87,7 @@ i18n_urls += decorated_patterns(
|
|
|
87
87
|
name="datalayer_versions",
|
|
88
88
|
),
|
|
89
89
|
path(
|
|
90
|
-
"datalayer/<int:map_id>/<uuid:pk>/<str:
|
|
90
|
+
"datalayer/<int:map_id>/<uuid:pk>/<str:ref>",
|
|
91
91
|
views.DataLayerVersion.as_view(),
|
|
92
92
|
name="datalayer_version",
|
|
93
93
|
),
|
|
@@ -155,8 +155,8 @@ map_urls = [
|
|
|
155
155
|
views.MapClone.as_view(),
|
|
156
156
|
name="map_clone",
|
|
157
157
|
),
|
|
158
|
-
|
|
159
|
-
|
|
158
|
+
path(
|
|
159
|
+
"map/<int:map_id>/datalayer/create/<uuid:pk>/",
|
|
160
160
|
views.DataLayerCreate.as_view(),
|
|
161
161
|
name="datalayer_create",
|
|
162
162
|
),
|