udata 9.1.2.dev30754__py2.py3-none-any.whl → 9.1.4.dev30983__py2.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 udata might be problematic. Click here for more details.
- tasks/helpers.py +6 -5
- udata/__init__.py +1 -1
- udata/api/__init__.py +2 -3
- udata/api/commands.py +0 -1
- udata/api/fields.py +22 -1
- udata/api_fields.py +22 -12
- udata/app.py +1 -1
- udata/assets.py +1 -1
- udata/auth/__init__.py +8 -12
- udata/commands/db.py +3 -3
- udata/commands/dcat.py +1 -1
- udata/commands/fixtures.py +110 -54
- udata/commands/init.py +2 -2
- udata/commands/tests/test_fixtures.py +71 -0
- udata/core/activity/tasks.py +1 -1
- udata/core/badges/models.py +0 -2
- udata/core/contact_point/api.py +1 -3
- udata/core/dataservices/tasks.py +1 -1
- udata/core/dataset/actions.py +2 -2
- udata/core/dataset/forms.py +0 -2
- udata/core/dataset/models.py +12 -10
- udata/core/dataset/rdf.py +1 -1
- udata/core/discussions/api.py +1 -1
- udata/core/discussions/models.py +2 -2
- udata/core/discussions/tasks.py +1 -1
- udata/core/organization/api.py +3 -4
- udata/core/organization/api_fields.py +2 -1
- udata/core/organization/apiv2.py +1 -1
- udata/core/reports/api.py +11 -0
- udata/core/reports/models.py +6 -1
- udata/core/reuse/metrics.py +1 -1
- udata/core/reuse/permissions.py +2 -1
- udata/core/reuse/search.py +2 -2
- udata/core/reuse/tasks.py +2 -2
- udata/core/spatial/commands.py +3 -3
- udata/core/spatial/factories.py +1 -1
- udata/core/spatial/forms.py +1 -1
- udata/core/spatial/models.py +2 -2
- udata/core/spatial/tests/test_models.py +1 -1
- udata/core/spatial/translations.py +3 -1
- udata/core/user/api.py +4 -4
- udata/core/user/metrics.py +1 -1
- udata/frontend/__init__.py +1 -1
- udata/harvest/actions.py +1 -1
- udata/harvest/backends/__init__.py +1 -1
- udata/harvest/tasks.py +0 -1
- udata/harvest/tests/factories.py +0 -2
- udata/harvest/tests/test_base_backend.py +0 -1
- udata/harvest/tests/test_dcat_backend.py +16 -17
- udata/migrations/2020-07-24-remove-s-from-scope-oauth.py +1 -1
- udata/migrations/2021-07-05-remove-unused-badges.py +0 -1
- udata/migrations/2023-02-08-rename-internal-dates.py +0 -2
- udata/migrations/2024-06-11-fix-reuse-datasets-references.py +0 -1
- udata/models/__init__.py +1 -0
- udata/routing.py +5 -0
- udata/search/commands.py +1 -1
- udata/search/query.py +1 -1
- udata/sentry.py +11 -2
- udata/settings.py +1 -0
- udata/tags.py +3 -3
- udata/tests/api/test_base_api.py +1 -1
- udata/tests/api/test_contact_points.py +4 -4
- udata/tests/api/test_datasets_api.py +10 -10
- udata/tests/api/test_organizations_api.py +39 -39
- udata/tests/api/test_reports_api.py +53 -3
- udata/tests/api/test_tags_api.py +2 -2
- udata/tests/api/test_transfer_api.py +1 -1
- udata/tests/apiv2/test_datasets.py +4 -4
- udata/tests/dataset/test_dataset_model.py +3 -3
- udata/tests/frontend/__init__.py +0 -2
- udata/tests/frontend/test_auth.py +0 -1
- udata/tests/organization/test_csv_adapter.py +0 -2
- udata/tests/organization/test_notifications.py +3 -3
- udata/tests/reuse/test_reuse_model.py +0 -1
- udata/tests/site/test_site_rdf.py +1 -3
- udata/tests/test_cors.py +0 -3
- udata/tests/test_owned.py +4 -4
- udata/tests/test_routing.py +1 -1
- udata/tests/test_tags.py +1 -1
- udata/tests/test_transfer.py +1 -2
- udata/tests/workers/test_jobs_commands.py +1 -1
- udata/utils.py +15 -14
- {udata-9.1.2.dev30754.dist-info → udata-9.1.4.dev30983.dist-info}/METADATA +20 -4
- {udata-9.1.2.dev30754.dist-info → udata-9.1.4.dev30983.dist-info}/RECORD +88 -89
- udata/commands/tests/fixtures.py +0 -44
- udata/tests/features/territories/commands.py +0 -9
- {udata-9.1.2.dev30754.dist-info → udata-9.1.4.dev30983.dist-info}/LICENSE +0 -0
- {udata-9.1.2.dev30754.dist-info → udata-9.1.4.dev30983.dist-info}/WHEEL +0 -0
- {udata-9.1.2.dev30754.dist-info → udata-9.1.4.dev30983.dist-info}/entry_points.txt +0 -0
- {udata-9.1.2.dev30754.dist-info → udata-9.1.4.dev30983.dist-info}/top_level.txt +0 -0
udata/search/query.py
CHANGED
udata/sentry.py
CHANGED
|
@@ -8,7 +8,9 @@ from werkzeug.exceptions import HTTPException
|
|
|
8
8
|
from udata import entrypoints
|
|
9
9
|
from udata.core.storages.api import UploadProgress
|
|
10
10
|
|
|
11
|
+
from .app import UDataApp
|
|
11
12
|
from .auth import PermissionDenied
|
|
13
|
+
from .frontend import package_version
|
|
12
14
|
|
|
13
15
|
log = logging.getLogger(__name__)
|
|
14
16
|
|
|
@@ -24,7 +26,7 @@ ERROR_PARSE_DSN_MSG = "Unable to parse Sentry DSN"
|
|
|
24
26
|
IGNORED_EXCEPTIONS = HTTPException, PermissionDenied, UploadProgress
|
|
25
27
|
|
|
26
28
|
|
|
27
|
-
def public_dsn(dsn):
|
|
29
|
+
def public_dsn(dsn: str) -> str | None:
|
|
28
30
|
"""Check if DSN is public or raise a warning and turn it into a public one"""
|
|
29
31
|
m = RE_DSN.match(dsn)
|
|
30
32
|
if not m:
|
|
@@ -41,7 +43,7 @@ def public_dsn(dsn):
|
|
|
41
43
|
return public
|
|
42
44
|
|
|
43
45
|
|
|
44
|
-
def init_app(app):
|
|
46
|
+
def init_app(app: UDataApp):
|
|
45
47
|
if app.config["SENTRY_DSN"]:
|
|
46
48
|
try:
|
|
47
49
|
import sentry_sdk
|
|
@@ -62,6 +64,13 @@ def init_app(app):
|
|
|
62
64
|
dsn=app.config["SENTRY_PUBLIC_DSN"],
|
|
63
65
|
integrations=[FlaskIntegration(), CeleryIntegration()],
|
|
64
66
|
ignore_errors=list(exceptions),
|
|
67
|
+
release=f"udata@{package_version('udata')}",
|
|
68
|
+
environment=app.config.get("SITE_ID", None),
|
|
69
|
+
# Set traces_sample_rate to 1.0 to capture 100%
|
|
70
|
+
# of transactions for performance monitoring.
|
|
71
|
+
# Sentry recommends adjusting this value in production.
|
|
72
|
+
traces_sample_rate=app.config.get("SENTRY_SAMPLE_RATE", None),
|
|
73
|
+
profiles_sample_rate=app.config.get("SENTRY_SAMPLE_RATE", None),
|
|
65
74
|
)
|
|
66
75
|
|
|
67
76
|
# Set log level
|
udata/settings.py
CHANGED
|
@@ -113,6 +113,7 @@ class Defaults(object):
|
|
|
113
113
|
SENTRY_USER_ATTRS = ["slug", "email", "fullname"]
|
|
114
114
|
SENTRY_LOGGING = "WARNING"
|
|
115
115
|
SENTRY_IGNORE_EXCEPTIONS = []
|
|
116
|
+
SENTRY_SAMPLE_RATE: float = 1.0
|
|
116
117
|
|
|
117
118
|
# Flask WTF settings
|
|
118
119
|
CSRF_SESSION_KEY = "Default uData csrf key"
|
udata/tags.py
CHANGED
|
@@ -6,11 +6,11 @@ MIN_TAG_LENGTH = LocalProxy(lambda: current_app.config["TAG_MIN_LENGTH"])
|
|
|
6
6
|
MAX_TAG_LENGTH = LocalProxy(lambda: current_app.config["TAG_MAX_LENGTH"])
|
|
7
7
|
|
|
8
8
|
|
|
9
|
-
def slug(value):
|
|
9
|
+
def slug(value: str) -> str:
|
|
10
10
|
return slugify(value.lower())
|
|
11
11
|
|
|
12
12
|
|
|
13
|
-
def normalize(value):
|
|
13
|
+
def normalize(value: str) -> str:
|
|
14
14
|
value = slug(value)
|
|
15
15
|
if len(value) < MIN_TAG_LENGTH:
|
|
16
16
|
value = ""
|
|
@@ -19,5 +19,5 @@ def normalize(value):
|
|
|
19
19
|
return value
|
|
20
20
|
|
|
21
21
|
|
|
22
|
-
def tags_list(value):
|
|
22
|
+
def tags_list(value: str) -> list:
|
|
23
23
|
return list(set(slug(tag) for tag in value.split(",") if tag.strip()))
|
udata/tests/api/test_base_api.py
CHANGED
|
@@ -14,18 +14,18 @@ class ContactPointAPITest:
|
|
|
14
14
|
modules = []
|
|
15
15
|
|
|
16
16
|
def test_contact_point_api_update(self, api):
|
|
17
|
-
|
|
17
|
+
api.login()
|
|
18
18
|
contact_point = ContactPointFactory()
|
|
19
19
|
data = contact_point.to_dict()
|
|
20
20
|
data["email"] = "new.email@newdomain.com"
|
|
21
21
|
response = api.put(url_for("api.contact_point", contact_point=contact_point), data)
|
|
22
22
|
assert200(response)
|
|
23
|
-
assert ContactPoint.objects.count()
|
|
23
|
+
assert ContactPoint.objects.count() == 1
|
|
24
24
|
assert ContactPoint.objects.first().email == "new.email@newdomain.com"
|
|
25
25
|
|
|
26
26
|
def test_contact_point_api_delete(self, api):
|
|
27
|
-
|
|
27
|
+
api.login()
|
|
28
28
|
contact_point = ContactPointFactory()
|
|
29
29
|
response = api.delete(url_for("api.contact_point", contact_point=contact_point))
|
|
30
30
|
assert204(response)
|
|
31
|
-
assert ContactPoint.objects.count()
|
|
31
|
+
assert ContactPoint.objects.count() == 0
|
|
@@ -42,7 +42,7 @@ from udata.i18n import gettext as _
|
|
|
42
42
|
from udata.models import CommunityResource, Dataset, Follow, Member, db
|
|
43
43
|
from udata.tags import MAX_TAG_LENGTH, MIN_TAG_LENGTH
|
|
44
44
|
from udata.tests.features.territories import create_geozones_fixtures
|
|
45
|
-
from udata.tests.helpers import assert200,
|
|
45
|
+
from udata.tests.helpers import assert200, assert404
|
|
46
46
|
from udata.utils import faker, unique_string
|
|
47
47
|
|
|
48
48
|
from . import APITestCase
|
|
@@ -839,7 +839,7 @@ class DatasetAPITest(APITestCase):
|
|
|
839
839
|
dataset.reload()
|
|
840
840
|
assert dataset.resources[0].schema["url"] == "http://example.com"
|
|
841
841
|
assert dataset.resources[0].schema["name"] == "etalab/schema-irve-statique"
|
|
842
|
-
assert dataset.resources[0].schema["version"]
|
|
842
|
+
assert dataset.resources[0].schema["version"] is None
|
|
843
843
|
|
|
844
844
|
resource_data["schema"] = {"name": "etalab/schema-irve-statique"}
|
|
845
845
|
data["resources"].append(resource_data)
|
|
@@ -848,8 +848,8 @@ class DatasetAPITest(APITestCase):
|
|
|
848
848
|
|
|
849
849
|
dataset.reload()
|
|
850
850
|
assert dataset.resources[0].schema["name"] == "etalab/schema-irve-statique"
|
|
851
|
-
assert dataset.resources[0].schema["url"]
|
|
852
|
-
assert dataset.resources[0].schema["version"]
|
|
851
|
+
assert dataset.resources[0].schema["url"] is None
|
|
852
|
+
assert dataset.resources[0].schema["version"] is None
|
|
853
853
|
|
|
854
854
|
resource_data["schema"] = {"name": "etalab/schema-irve-statique", "version": "2.2.0"}
|
|
855
855
|
data["resources"].append(resource_data)
|
|
@@ -858,7 +858,7 @@ class DatasetAPITest(APITestCase):
|
|
|
858
858
|
|
|
859
859
|
dataset.reload()
|
|
860
860
|
assert dataset.resources[0].schema["name"] == "etalab/schema-irve-statique"
|
|
861
|
-
assert dataset.resources[0].schema["url"]
|
|
861
|
+
assert dataset.resources[0].schema["url"] is None
|
|
862
862
|
assert dataset.resources[0].schema["version"] == "2.2.0"
|
|
863
863
|
|
|
864
864
|
resource_data["schema"] = {
|
|
@@ -870,7 +870,7 @@ class DatasetAPITest(APITestCase):
|
|
|
870
870
|
|
|
871
871
|
dataset.reload()
|
|
872
872
|
assert dataset.resources[0].schema["name"] == "etalab/schema-irve-statique"
|
|
873
|
-
assert dataset.resources[0].schema["url"]
|
|
873
|
+
assert dataset.resources[0].schema["url"] is None
|
|
874
874
|
assert dataset.resources[0].schema["version"] == "2.2.1"
|
|
875
875
|
|
|
876
876
|
# Putting `None` as the schema argument do not remove the schema
|
|
@@ -884,7 +884,7 @@ class DatasetAPITest(APITestCase):
|
|
|
884
884
|
|
|
885
885
|
dataset.reload()
|
|
886
886
|
assert dataset.resources[0].schema["name"] == "etalab/schema-irve-statique"
|
|
887
|
-
assert dataset.resources[0].schema["url"]
|
|
887
|
+
assert dataset.resources[0].schema["url"] is None
|
|
888
888
|
assert dataset.resources[0].schema["version"] == "2.2.1"
|
|
889
889
|
|
|
890
890
|
# Putting `None` as the schema name and version remove the schema
|
|
@@ -897,9 +897,9 @@ class DatasetAPITest(APITestCase):
|
|
|
897
897
|
self.assert200(response)
|
|
898
898
|
|
|
899
899
|
dataset.reload()
|
|
900
|
-
assert dataset.resources[0].schema["name"]
|
|
901
|
-
assert dataset.resources[0].schema["url"]
|
|
902
|
-
assert dataset.resources[0].schema["version"]
|
|
900
|
+
assert dataset.resources[0].schema["name"] is None
|
|
901
|
+
assert dataset.resources[0].schema["url"] is None
|
|
902
|
+
assert dataset.resources[0].schema["version"] is None
|
|
903
903
|
|
|
904
904
|
|
|
905
905
|
class DatasetBadgeAPITest(APITestCase):
|
|
@@ -72,7 +72,7 @@ class OrganizationAPITest:
|
|
|
72
72
|
user = api.login()
|
|
73
73
|
response = api.post(url_for("api.organizations"), data)
|
|
74
74
|
assert201(response)
|
|
75
|
-
assert Organization.objects.count()
|
|
75
|
+
assert Organization.objects.count() == 1
|
|
76
76
|
|
|
77
77
|
org = Organization.objects.first()
|
|
78
78
|
member = org.member(user)
|
|
@@ -89,7 +89,7 @@ class OrganizationAPITest:
|
|
|
89
89
|
data["description"] = "new description"
|
|
90
90
|
response = api.put(url_for("api.organization", org=org), data)
|
|
91
91
|
assert200(response)
|
|
92
|
-
assert Organization.objects.count()
|
|
92
|
+
assert Organization.objects.count() == 1
|
|
93
93
|
assert Organization.objects.first().description == "new description"
|
|
94
94
|
|
|
95
95
|
def test_organization_api_update_business_number_id(self, api):
|
|
@@ -101,7 +101,7 @@ class OrganizationAPITest:
|
|
|
101
101
|
data["business_number_id"] = "13002526500013"
|
|
102
102
|
response = api.put(url_for("api.organization", org=org), data)
|
|
103
103
|
assert200(response)
|
|
104
|
-
assert Organization.objects.count()
|
|
104
|
+
assert Organization.objects.count() == 1
|
|
105
105
|
assert Organization.objects.first().business_number_id == "13002526500013"
|
|
106
106
|
|
|
107
107
|
def test_organization_api_update_business_number_id_failing(self, api):
|
|
@@ -147,7 +147,7 @@ class OrganizationAPITest:
|
|
|
147
147
|
api.login()
|
|
148
148
|
response = api.put(url_for("api.organization", org=org), data)
|
|
149
149
|
assert403(response)
|
|
150
|
-
assert Organization.objects.count()
|
|
150
|
+
assert Organization.objects.count() == 1
|
|
151
151
|
assert Organization.objects.first().description == org.description
|
|
152
152
|
|
|
153
153
|
def test_organization_api_delete(self, api):
|
|
@@ -157,7 +157,7 @@ class OrganizationAPITest:
|
|
|
157
157
|
org = OrganizationFactory(members=[member])
|
|
158
158
|
response = api.delete(url_for("api.organization", org=org))
|
|
159
159
|
assert204(response)
|
|
160
|
-
assert Organization.objects.count()
|
|
160
|
+
assert Organization.objects.count() == 1
|
|
161
161
|
assert Organization.objects[0].deleted is not None
|
|
162
162
|
|
|
163
163
|
def test_organization_api_delete_deleted(self, api):
|
|
@@ -175,7 +175,7 @@ class OrganizationAPITest:
|
|
|
175
175
|
org = OrganizationFactory(members=[member])
|
|
176
176
|
response = api.delete(url_for("api.organization", org=org))
|
|
177
177
|
assert403(response)
|
|
178
|
-
assert Organization.objects.count()
|
|
178
|
+
assert Organization.objects.count() == 1
|
|
179
179
|
assert Organization.objects[0].deleted is None
|
|
180
180
|
|
|
181
181
|
def test_organization_api_delete_as_non_member_forbidden(self, api):
|
|
@@ -184,7 +184,7 @@ class OrganizationAPITest:
|
|
|
184
184
|
org = OrganizationFactory()
|
|
185
185
|
response = api.delete(url_for("api.organization", org=org))
|
|
186
186
|
assert403(response)
|
|
187
|
-
assert Organization.objects.count()
|
|
187
|
+
assert Organization.objects.count() == 1
|
|
188
188
|
assert Organization.objects[0].deleted is None
|
|
189
189
|
|
|
190
190
|
|
|
@@ -200,10 +200,10 @@ class MembershipAPITest:
|
|
|
200
200
|
assert201(response)
|
|
201
201
|
|
|
202
202
|
organization.reload()
|
|
203
|
-
assert len(organization.requests)
|
|
204
|
-
assert len(organization.pending_requests)
|
|
205
|
-
assert len(organization.refused_requests)
|
|
206
|
-
assert len(organization.accepted_requests)
|
|
203
|
+
assert len(organization.requests) == 1
|
|
204
|
+
assert len(organization.pending_requests) == 1
|
|
205
|
+
assert len(organization.refused_requests) == 0
|
|
206
|
+
assert len(organization.accepted_requests) == 0
|
|
207
207
|
|
|
208
208
|
request = organization.requests[0]
|
|
209
209
|
assert request.user == user
|
|
@@ -223,10 +223,10 @@ class MembershipAPITest:
|
|
|
223
223
|
assert200(response)
|
|
224
224
|
|
|
225
225
|
organization.reload()
|
|
226
|
-
assert len(organization.requests)
|
|
227
|
-
assert len(organization.pending_requests)
|
|
228
|
-
assert len(organization.refused_requests)
|
|
229
|
-
assert len(organization.accepted_requests)
|
|
226
|
+
assert len(organization.requests) == 1
|
|
227
|
+
assert len(organization.pending_requests) == 1
|
|
228
|
+
assert len(organization.refused_requests) == 0
|
|
229
|
+
assert len(organization.accepted_requests) == 0
|
|
230
230
|
|
|
231
231
|
request = organization.requests[0]
|
|
232
232
|
assert request.user == user
|
|
@@ -326,10 +326,10 @@ class MembershipAPITest:
|
|
|
326
326
|
assert response.json["role"] == "editor"
|
|
327
327
|
|
|
328
328
|
organization.reload()
|
|
329
|
-
assert len(organization.requests)
|
|
330
|
-
assert len(organization.pending_requests)
|
|
331
|
-
assert len(organization.refused_requests)
|
|
332
|
-
assert len(organization.accepted_requests)
|
|
329
|
+
assert len(organization.requests) == 1
|
|
330
|
+
assert len(organization.pending_requests) == 0
|
|
331
|
+
assert len(organization.refused_requests) == 0
|
|
332
|
+
assert len(organization.accepted_requests) == 1
|
|
333
333
|
assert organization.is_member(applicant)
|
|
334
334
|
|
|
335
335
|
request = organization.requests[0]
|
|
@@ -380,10 +380,10 @@ class MembershipAPITest:
|
|
|
380
380
|
assert200(response)
|
|
381
381
|
|
|
382
382
|
organization.reload()
|
|
383
|
-
assert len(organization.requests)
|
|
384
|
-
assert len(organization.pending_requests)
|
|
385
|
-
assert len(organization.refused_requests)
|
|
386
|
-
assert len(organization.accepted_requests)
|
|
383
|
+
assert len(organization.requests) == 1
|
|
384
|
+
assert len(organization.pending_requests) == 0
|
|
385
|
+
assert len(organization.refused_requests) == 1
|
|
386
|
+
assert len(organization.accepted_requests) == 0
|
|
387
387
|
assert not organization.is_member(applicant)
|
|
388
388
|
|
|
389
389
|
request = organization.requests[0]
|
|
@@ -548,12 +548,12 @@ class MembershipAPITest:
|
|
|
548
548
|
to_follow.count_followers()
|
|
549
549
|
assert to_follow.get_metrics()["followers"] == 1
|
|
550
550
|
|
|
551
|
-
assert Follow.objects.following(to_follow).count()
|
|
552
|
-
assert Follow.objects.followers(to_follow).count()
|
|
551
|
+
assert Follow.objects.following(to_follow).count() == 0
|
|
552
|
+
assert Follow.objects.followers(to_follow).count() == 1
|
|
553
553
|
follow = Follow.objects.followers(to_follow).first()
|
|
554
554
|
assert isinstance(follow.following, Organization)
|
|
555
|
-
assert Follow.objects.following(user).count()
|
|
556
|
-
assert Follow.objects.followers(user).count()
|
|
555
|
+
assert Follow.objects.following(user).count() == 1
|
|
556
|
+
assert Follow.objects.followers(user).count() == 0
|
|
557
557
|
|
|
558
558
|
def test_unfollow_org(self, api):
|
|
559
559
|
"""It should unfollow the organization on DELETE"""
|
|
@@ -567,12 +567,12 @@ class MembershipAPITest:
|
|
|
567
567
|
|
|
568
568
|
nb_followers = Follow.objects.followers(to_follow).count()
|
|
569
569
|
|
|
570
|
-
assert nb_followers
|
|
570
|
+
assert nb_followers == 0
|
|
571
571
|
assert response.json["followers"] == nb_followers
|
|
572
572
|
|
|
573
|
-
assert Follow.objects.following(to_follow).count()
|
|
574
|
-
assert Follow.objects.following(user).count()
|
|
575
|
-
assert Follow.objects.followers(user).count()
|
|
573
|
+
assert Follow.objects.following(to_follow).count() == 0
|
|
574
|
+
assert Follow.objects.following(user).count() == 0
|
|
575
|
+
assert Follow.objects.followers(user).count() == 0
|
|
576
576
|
|
|
577
577
|
def test_suggest_organizations_api(self, api):
|
|
578
578
|
"""It should suggest organizations"""
|
|
@@ -658,13 +658,13 @@ class MembershipAPITest:
|
|
|
658
658
|
|
|
659
659
|
response = api.get(url_for("api.suggest_organizations"), qs={"q": "xxxxxx", "size": "5"})
|
|
660
660
|
assert200(response)
|
|
661
|
-
assert len(response.json)
|
|
661
|
+
assert len(response.json) == 0
|
|
662
662
|
|
|
663
663
|
def test_suggest_organizations_api_empty(self, api):
|
|
664
664
|
"""It should not provide organization suggestion if no data"""
|
|
665
665
|
response = api.get(url_for("api.suggest_organizations"), qs={"q": "xxxxxx", "size": "5"})
|
|
666
666
|
assert200(response)
|
|
667
|
-
assert len(response.json)
|
|
667
|
+
assert len(response.json) == 0
|
|
668
668
|
|
|
669
669
|
def test_suggest_organizations_homonyms(self, api):
|
|
670
670
|
"""It should suggest organizations and not deduplicate homonyms"""
|
|
@@ -673,7 +673,7 @@ class MembershipAPITest:
|
|
|
673
673
|
response = api.get(url_for("api.suggest_organizations"), qs={"q": "homonym", "size": "5"})
|
|
674
674
|
assert200(response)
|
|
675
675
|
|
|
676
|
-
assert len(response.json)
|
|
676
|
+
assert len(response.json) == 2
|
|
677
677
|
|
|
678
678
|
for suggestion in response.json:
|
|
679
679
|
assert suggestion["name"] == "homonym"
|
|
@@ -749,7 +749,7 @@ class OrganizationDatasetsAPITest:
|
|
|
749
749
|
response = api.get(url_for("api.org_datasets", org=org), qs={"page_size": 2})
|
|
750
750
|
|
|
751
751
|
assert200(response)
|
|
752
|
-
assert len(response.json["data"])
|
|
752
|
+
assert len(response.json["data"]) == 2
|
|
753
753
|
|
|
754
754
|
|
|
755
755
|
class OrganizationReusesAPITest:
|
|
@@ -841,7 +841,7 @@ class OrganizationBadgeAPITest:
|
|
|
841
841
|
response = api.post(url, data)
|
|
842
842
|
assert201(response)
|
|
843
843
|
self.organization.reload()
|
|
844
|
-
assert len(self.organization.badges)
|
|
844
|
+
assert len(self.organization.badges) == 1
|
|
845
845
|
|
|
846
846
|
def test_create_same(self, api):
|
|
847
847
|
data = self.factory.as_dict()
|
|
@@ -852,7 +852,7 @@ class OrganizationBadgeAPITest:
|
|
|
852
852
|
response = api.post(url, data)
|
|
853
853
|
assert200(response)
|
|
854
854
|
self.organization.reload()
|
|
855
|
-
assert len(self.organization.badges)
|
|
855
|
+
assert len(self.organization.badges) == 1
|
|
856
856
|
|
|
857
857
|
def test_create_2nd(self, api):
|
|
858
858
|
# Explicitely setting the kind to avoid collisions given the
|
|
@@ -865,7 +865,7 @@ class OrganizationBadgeAPITest:
|
|
|
865
865
|
response = api.post(url, data)
|
|
866
866
|
assert201(response)
|
|
867
867
|
self.organization.reload()
|
|
868
|
-
assert len(self.organization.badges)
|
|
868
|
+
assert len(self.organization.badges) == 2
|
|
869
869
|
|
|
870
870
|
def test_delete(self, api):
|
|
871
871
|
badge = self.factory()
|
|
@@ -876,7 +876,7 @@ class OrganizationBadgeAPITest:
|
|
|
876
876
|
response = api.delete(url)
|
|
877
877
|
assert204(response)
|
|
878
878
|
self.organization.reload()
|
|
879
|
-
assert len(self.organization.badges)
|
|
879
|
+
assert len(self.organization.badges) == 0
|
|
880
880
|
|
|
881
881
|
def test_delete_404(self, api):
|
|
882
882
|
kind = str(self.factory().kind)
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
from flask import url_for
|
|
2
|
-
from mongoengine.base.datastructures import LazyReference
|
|
3
2
|
|
|
4
3
|
from udata.core.dataset.factories import DatasetFactory
|
|
5
4
|
from udata.core.dataset.models import Dataset
|
|
@@ -9,8 +8,8 @@ from udata.core.reports.constants import (
|
|
|
9
8
|
reports_reasons_translations,
|
|
10
9
|
)
|
|
11
10
|
from udata.core.reports.models import Report
|
|
12
|
-
from udata.core.
|
|
13
|
-
from udata.
|
|
11
|
+
from udata.core.reuse.factories import ReuseFactory
|
|
12
|
+
from udata.core.user.factories import AdminFactory, UserFactory
|
|
14
13
|
|
|
15
14
|
from . import APITestCase
|
|
16
15
|
|
|
@@ -100,6 +99,11 @@ class ReportsAPITest(APITestCase):
|
|
|
100
99
|
reports[1].reload()
|
|
101
100
|
self.assertIsNotNone(reports[1].subject_deleted_at)
|
|
102
101
|
|
|
102
|
+
# Should be logged as admin
|
|
103
|
+
response = self.get(url_for("api.reports"))
|
|
104
|
+
self.assert403(response)
|
|
105
|
+
|
|
106
|
+
self.login(AdminFactory())
|
|
103
107
|
response = self.get(url_for("api.reports"))
|
|
104
108
|
self.assert200(response)
|
|
105
109
|
|
|
@@ -119,3 +123,49 @@ class ReportsAPITest(APITestCase):
|
|
|
119
123
|
self.assertEqual(REASON_SPAM, reports[1]["reason"])
|
|
120
124
|
self.assertEqual(str(user.id), reports[1]["by"]["id"])
|
|
121
125
|
self.assertIsNotNone(reports[1]["subject_deleted_at"])
|
|
126
|
+
|
|
127
|
+
def test_reports_api_list(self):
|
|
128
|
+
user = UserFactory()
|
|
129
|
+
|
|
130
|
+
spam_dataset = DatasetFactory.create(owner=user)
|
|
131
|
+
spam_reuse = ReuseFactory.create(owner=user)
|
|
132
|
+
|
|
133
|
+
Report(subject=spam_dataset, reason="spam").save()
|
|
134
|
+
Report(subject=spam_reuse, reason="spam").save()
|
|
135
|
+
|
|
136
|
+
# Should be logged as admin
|
|
137
|
+
response = self.get(url_for("api.reports"))
|
|
138
|
+
self.assert401(response)
|
|
139
|
+
|
|
140
|
+
self.login(AdminFactory())
|
|
141
|
+
response = self.get(url_for("api.reports"))
|
|
142
|
+
self.assert200(response)
|
|
143
|
+
|
|
144
|
+
payload = response.json
|
|
145
|
+
self.assertEqual(payload["total"], 2)
|
|
146
|
+
# Returned by order of creation by default
|
|
147
|
+
self.assertEqual(payload["data"][0]["subject"]["id"], str(spam_dataset.id))
|
|
148
|
+
self.assertEqual(
|
|
149
|
+
payload["data"][0]["self_api_url"],
|
|
150
|
+
url_for("api.report", report=payload["data"][0]["id"], _external=True),
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
self.assertEqual(payload["data"][1]["subject"]["id"], str(spam_reuse.id))
|
|
154
|
+
|
|
155
|
+
def test_reports_api_get(self):
|
|
156
|
+
user = UserFactory()
|
|
157
|
+
|
|
158
|
+
spam_dataset = DatasetFactory.create(owner=user)
|
|
159
|
+
|
|
160
|
+
report = Report(subject=spam_dataset, reason="spam").save()
|
|
161
|
+
|
|
162
|
+
# Should be logged as admin
|
|
163
|
+
response = self.get(url_for("api.report", report=report))
|
|
164
|
+
self.assert401(response)
|
|
165
|
+
|
|
166
|
+
self.login(AdminFactory())
|
|
167
|
+
response = self.get(url_for("api.report", report=report))
|
|
168
|
+
self.assert200(response)
|
|
169
|
+
|
|
170
|
+
payload = response.json
|
|
171
|
+
self.assertEqual(payload["subject"]["id"], str(spam_dataset.id))
|
udata/tests/api/test_tags_api.py
CHANGED
|
@@ -61,10 +61,10 @@ class TagsAPITest:
|
|
|
61
61
|
|
|
62
62
|
response = api.get(url_for("api.suggest_tags"), qs={"q": "bbbb", "size": "5"})
|
|
63
63
|
assert200(response)
|
|
64
|
-
assert len(response.json)
|
|
64
|
+
assert len(response.json) == 0
|
|
65
65
|
|
|
66
66
|
def test_suggest_tags_api_empty(self, api):
|
|
67
67
|
"""It should not provide tag suggestion if no data"""
|
|
68
68
|
response = api.get(url_for("api.suggest_tags"), qs={"q": "bbbb", "size": "5"})
|
|
69
69
|
assert200(response)
|
|
70
|
-
assert len(response.json)
|
|
70
|
+
assert len(response.json) == 0
|
|
@@ -83,7 +83,7 @@ class DatasetResourceAPIV2Test(APITestCase):
|
|
|
83
83
|
assert data["total"] == len(resources)
|
|
84
84
|
assert data["page"] == 1
|
|
85
85
|
assert data["page_size"] == DEFAULT_PAGE_SIZE
|
|
86
|
-
assert data["next_page"]
|
|
86
|
+
assert data["next_page"] is None
|
|
87
87
|
assert data["previous_page"] is None
|
|
88
88
|
|
|
89
89
|
def test_get_missing_param(self):
|
|
@@ -97,7 +97,7 @@ class DatasetResourceAPIV2Test(APITestCase):
|
|
|
97
97
|
assert data["total"] == len(resources)
|
|
98
98
|
assert data["page"] == 1
|
|
99
99
|
assert data["page_size"] == DEFAULT_PAGE_SIZE
|
|
100
|
-
assert data["next_page"]
|
|
100
|
+
assert data["next_page"] is None
|
|
101
101
|
assert data["previous_page"] is None
|
|
102
102
|
|
|
103
103
|
def test_get_next_page(self):
|
|
@@ -129,7 +129,7 @@ class DatasetResourceAPIV2Test(APITestCase):
|
|
|
129
129
|
assert data["total"] == len(resources)
|
|
130
130
|
assert data["page"] == 2
|
|
131
131
|
assert data["page_size"] == DEFAULT_PAGE_SIZE
|
|
132
|
-
assert data["next_page"]
|
|
132
|
+
assert data["next_page"] is None
|
|
133
133
|
assert data["previous_page"] == url_for(
|
|
134
134
|
"apiv2.resources",
|
|
135
135
|
dataset=dataset.id,
|
|
@@ -196,7 +196,7 @@ class DatasetResourceAPIV2Test(APITestCase):
|
|
|
196
196
|
assert data["total"] == nb_resources__of_specific_type
|
|
197
197
|
assert data["page"] == 2
|
|
198
198
|
assert data["page_size"] == DEFAULT_PAGE_SIZE
|
|
199
|
-
assert data["next_page"]
|
|
199
|
+
assert data["next_page"] is None
|
|
200
200
|
assert data["previous_page"] == url_for(
|
|
201
201
|
"apiv2.resources",
|
|
202
202
|
dataset=dataset.id,
|
|
@@ -301,15 +301,15 @@ class DatasetModelTest:
|
|
|
301
301
|
|
|
302
302
|
def test_dataset_without_private(self):
|
|
303
303
|
dataset = DatasetFactory()
|
|
304
|
-
assert dataset.private
|
|
304
|
+
assert dataset.private is False
|
|
305
305
|
|
|
306
306
|
dataset.private = None
|
|
307
307
|
dataset.save()
|
|
308
|
-
assert dataset.private
|
|
308
|
+
assert dataset.private is False
|
|
309
309
|
|
|
310
310
|
dataset.private = True
|
|
311
311
|
dataset.save()
|
|
312
|
-
assert dataset.private
|
|
312
|
+
assert dataset.private is True
|
|
313
313
|
|
|
314
314
|
|
|
315
315
|
class ResourceModelTest:
|
udata/tests/frontend/__init__.py
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import pytest
|
|
2
2
|
|
|
3
|
-
from udata.core.dataset.csv import DatasetCsvAdapter, ResourcesCsvAdapter
|
|
4
3
|
from udata.core.dataset.factories import DatasetFactory, ResourceFactory
|
|
5
|
-
from udata.core.dataset.models import Dataset
|
|
6
4
|
from udata.core.organization.csv import OrganizationCsvAdapter
|
|
7
5
|
from udata.core.organization.factories import OrganizationFactory
|
|
8
6
|
from udata.core.organization.models import Organization
|
|
@@ -17,11 +17,11 @@ class OrganizationNotificationsTest:
|
|
|
17
17
|
members = [Member(user=editor, role="editor"), Member(user=admin, role="admin")]
|
|
18
18
|
org = OrganizationFactory(members=members, requests=[request])
|
|
19
19
|
|
|
20
|
-
assert len(membership_request_notifications(applicant))
|
|
21
|
-
assert len(membership_request_notifications(editor))
|
|
20
|
+
assert len(membership_request_notifications(applicant)) == 0
|
|
21
|
+
assert len(membership_request_notifications(editor)) == 0
|
|
22
22
|
|
|
23
23
|
notifications = membership_request_notifications(admin)
|
|
24
|
-
assert len(notifications)
|
|
24
|
+
assert len(notifications) == 1
|
|
25
25
|
dt, details = notifications[0]
|
|
26
26
|
assert_equal_dates(dt, request.created)
|
|
27
27
|
assert details["id"] == request.id
|
|
@@ -254,9 +254,7 @@ class SiteRdfViewsTest:
|
|
|
254
254
|
dataset_b = DatasetFactory.create()
|
|
255
255
|
dataset_c = DatasetFactory.create()
|
|
256
256
|
|
|
257
|
-
|
|
258
|
-
datasets=[dataset_a.id], harvest=HarvestMetadataFactory()
|
|
259
|
-
)
|
|
257
|
+
DataserviceFactory.create(datasets=[dataset_a.id], harvest=HarvestMetadataFactory())
|
|
260
258
|
dataservice_b = DataserviceFactory.create(datasets=[dataset_b.id])
|
|
261
259
|
dataservice_x = DataserviceFactory.create(datasets=[dataset_a.id, dataset_c.id])
|
|
262
260
|
dataservice_y = DataserviceFactory.create(datasets=[])
|
udata/tests/test_cors.py
CHANGED
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
from datetime import datetime
|
|
2
2
|
|
|
3
|
-
import pytest
|
|
4
3
|
from flask import url_for
|
|
5
4
|
|
|
6
5
|
from udata.core.dataset.factories import DatasetFactory
|
|
7
|
-
from udata.core.topic.factories import TopicFactory
|
|
8
|
-
from udata.search import reindex
|
|
9
6
|
from udata.tests.api import APITestCase
|
|
10
7
|
from udata.tests.helpers import assert_status
|
|
11
8
|
|
udata/tests/test_owned.py
CHANGED
|
@@ -161,8 +161,8 @@ class OwnedQuerysetTest(DBTestMixin, TestCase):
|
|
|
161
161
|
result = Owned.objects.owned_by(org, user)
|
|
162
162
|
|
|
163
163
|
self.assertEqual(len(result), 2)
|
|
164
|
-
for
|
|
165
|
-
self.assertIn(
|
|
164
|
+
for owned_ in result:
|
|
165
|
+
self.assertIn(owned_, owneds)
|
|
166
166
|
|
|
167
|
-
for
|
|
168
|
-
self.assertNotIn(
|
|
167
|
+
for owned_ in excluded:
|
|
168
|
+
self.assertNotIn(owned_, result)
|
udata/tests/test_routing.py
CHANGED
|
@@ -273,7 +273,7 @@ class SlugAsSLugFieldWithFollowTest(AsSlugMixin):
|
|
|
273
273
|
assert404(client.get(second_url))
|
|
274
274
|
assert404(client.get(last_url))
|
|
275
275
|
|
|
276
|
-
assert SlugFollow.objects.count()
|
|
276
|
+
assert SlugFollow.objects.count() == 0
|
|
277
277
|
|
|
278
278
|
|
|
279
279
|
@pytest.mark.usefixtures("clean_db")
|