udata 12.0.2.dev10__py3-none-any.whl → 13.0.1.dev21__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.
- udata/api/__init__.py +1 -0
- udata/api_fields.py +10 -4
- udata/app.py +11 -10
- udata/auth/__init__.py +9 -10
- udata/auth/mails.py +137 -45
- udata/auth/views.py +5 -12
- udata/commands/__init__.py +2 -4
- udata/commands/info.py +1 -3
- udata/commands/tests/test_fixtures.py +6 -3
- udata/core/access_type/api.py +18 -0
- udata/core/access_type/constants.py +98 -0
- udata/core/access_type/models.py +44 -0
- udata/core/activity/models.py +1 -1
- udata/core/badges/models.py +1 -1
- udata/core/badges/tasks.py +35 -1
- udata/core/badges/tests/test_commands.py +2 -4
- udata/core/badges/tests/test_model.py +2 -2
- udata/core/badges/tests/test_tasks.py +55 -0
- udata/core/constants.py +1 -0
- udata/core/contact_point/models.py +8 -0
- udata/core/dataservices/api.py +10 -12
- udata/core/dataservices/apiv2.py +3 -1
- udata/core/dataservices/constants.py +0 -29
- udata/core/dataservices/models.py +44 -44
- udata/core/dataservices/rdf.py +2 -1
- udata/core/dataservices/search.py +5 -9
- udata/core/dataservices/tasks.py +33 -0
- udata/core/dataset/api.py +15 -24
- udata/core/dataset/api_fields.py +11 -0
- udata/core/dataset/apiv2.py +11 -0
- udata/core/dataset/constants.py +0 -1
- udata/core/dataset/forms.py +29 -0
- udata/core/dataset/models.py +24 -42
- udata/core/dataset/rdf.py +2 -1
- udata/core/dataset/search.py +2 -2
- udata/core/dataset/tasks.py +86 -8
- udata/core/discussions/mails.py +63 -0
- udata/core/discussions/tasks.py +4 -18
- udata/core/metrics/__init__.py +0 -6
- udata/core/organization/api.py +20 -14
- udata/core/organization/mails.py +144 -0
- udata/core/organization/models.py +2 -1
- udata/core/organization/rdf.py +3 -3
- udata/core/organization/search.py +1 -1
- udata/core/organization/tasks.py +21 -49
- udata/core/pages/tests/test_api.py +0 -2
- udata/core/reuse/api.py +29 -3
- udata/core/reuse/mails.py +21 -0
- udata/core/reuse/models.py +10 -1
- udata/core/reuse/search.py +1 -1
- udata/core/reuse/tasks.py +2 -3
- udata/core/site/api.py +27 -19
- udata/core/site/models.py +2 -6
- udata/core/site/rdf.py +2 -2
- udata/core/spatial/tests/test_api.py +17 -20
- udata/core/spatial/tests/test_models.py +3 -3
- udata/core/user/mails.py +54 -0
- udata/core/user/models.py +2 -3
- udata/core/user/tasks.py +8 -23
- udata/core/user/tests/test_user_model.py +2 -6
- udata/entrypoints.py +0 -6
- udata/features/identicon/tests/test_backends.py +3 -13
- udata/forms/fields.py +3 -3
- udata/forms/widgets.py +2 -2
- udata/frontend/__init__.py +3 -32
- udata/harvest/actions.py +4 -9
- udata/harvest/api.py +5 -14
- udata/harvest/backends/__init__.py +20 -11
- udata/harvest/backends/base.py +2 -2
- udata/harvest/backends/ckan/harvesters.py +2 -1
- udata/harvest/backends/dcat.py +3 -0
- udata/harvest/backends/maaf.py +1 -0
- udata/harvest/commands.py +6 -4
- udata/harvest/forms.py +9 -6
- udata/harvest/tasks.py +3 -5
- udata/harvest/tests/ckan/test_ckan_backend.py +300 -337
- udata/harvest/tests/ckan/test_ckan_backend_errors.py +94 -99
- udata/harvest/tests/ckan/test_ckan_backend_filters.py +128 -122
- udata/harvest/tests/ckan/test_dkan_backend.py +39 -51
- udata/harvest/tests/dcat/bnodes.xml +17 -1
- udata/harvest/tests/dcat/datara--5a26b0f6-0ccf-46ad-ac58-734054b91977.rdf.xml +255 -0
- udata/harvest/tests/dcat/datara--f40c3860-7236-4b30-a141-23b8ae33f7b2.rdf.xml +289 -0
- udata/harvest/tests/factories.py +1 -1
- udata/harvest/tests/test_actions.py +11 -9
- udata/harvest/tests/test_api.py +4 -5
- udata/harvest/tests/test_base_backend.py +5 -4
- udata/harvest/tests/test_dcat_backend.py +72 -16
- udata/harvest/tests/test_models.py +2 -4
- udata/harvest/tests/test_notifications.py +2 -4
- udata/harvest/tests/test_tasks.py +2 -3
- udata/mail.py +90 -53
- udata/migrations/2025-01-05-dataservices-fields-changes.py +8 -14
- udata/migrations/2025-10-21-remove-ckan-harvest-modified-at.py +28 -0
- udata/migrations/2025-10-29-harvesters-sources-integrity.py +27 -0
- udata/models/__init__.py +0 -2
- udata/mongo/extras_fields.py +4 -3
- udata/mongo/taglist_field.py +3 -3
- udata/rdf.py +65 -20
- udata/sentry.py +3 -4
- udata/settings.py +15 -13
- udata/tags.py +5 -5
- udata/tasks.py +3 -3
- udata/templates/mail/message.html +65 -0
- udata/templates/mail/message.txt +16 -0
- udata/tests/__init__.py +40 -58
- udata/tests/api/__init__.py +87 -2
- udata/tests/api/test_activities_api.py +17 -23
- udata/tests/api/test_auth_api.py +2 -4
- udata/tests/api/test_contact_points.py +48 -54
- udata/tests/api/test_dataservices_api.py +65 -97
- udata/tests/api/test_datasets_api.py +171 -56
- udata/tests/api/test_me_api.py +4 -6
- udata/tests/api/test_organizations_api.py +19 -38
- udata/tests/api/test_reports_api.py +0 -4
- udata/tests/api/test_reuses_api.py +99 -23
- udata/tests/api/test_security_api.py +124 -0
- udata/tests/api/test_swagger.py +2 -3
- udata/tests/api/test_tags_api.py +6 -7
- udata/tests/api/test_transfer_api.py +0 -2
- udata/tests/api/test_user_api.py +8 -10
- udata/tests/apiv2/test_datasets.py +0 -4
- udata/tests/apiv2/test_me_api.py +0 -2
- udata/tests/apiv2/test_organizations.py +0 -2
- udata/tests/apiv2/test_swagger.py +2 -3
- udata/tests/apiv2/test_topics.py +0 -2
- udata/tests/cli/test_cli_base.py +14 -12
- udata/tests/cli/test_db_cli.py +51 -54
- udata/tests/contact_point/test_contact_point_models.py +2 -2
- udata/tests/dataservice/test_csv_adapter.py +2 -5
- udata/tests/dataservice/test_dataservice_rdf.py +64 -4
- udata/tests/dataservice/test_dataservice_tasks.py +36 -38
- udata/tests/dataset/test_csv_adapter.py +2 -5
- udata/tests/dataset/test_dataset_actions.py +2 -4
- udata/tests/dataset/test_dataset_commands.py +2 -4
- udata/tests/dataset/test_dataset_events.py +3 -3
- udata/tests/dataset/test_dataset_model.py +6 -7
- udata/tests/dataset/test_dataset_rdf.py +205 -16
- udata/tests/dataset/test_dataset_recommendations.py +2 -2
- udata/tests/dataset/test_dataset_tasks.py +66 -68
- udata/tests/dataset/test_resource_preview.py +39 -48
- udata/tests/dataset/test_transport_tasks.py +2 -2
- udata/tests/features/territories/__init__.py +0 -6
- udata/tests/features/territories/test_territories_api.py +25 -24
- udata/tests/forms/test_current_user_field.py +2 -2
- udata/tests/forms/test_dict_field.py +2 -4
- udata/tests/forms/test_extras_fields.py +2 -3
- udata/tests/forms/test_image_field.py +2 -2
- udata/tests/forms/test_model_field.py +2 -4
- udata/tests/forms/test_publish_as_field.py +2 -4
- udata/tests/forms/test_user_forms.py +26 -29
- udata/tests/frontend/test_auth.py +2 -3
- udata/tests/frontend/test_csv.py +5 -6
- udata/tests/frontend/test_error_handlers.py +2 -3
- udata/tests/frontend/test_hooks.py +5 -7
- udata/tests/frontend/test_markdown.py +3 -4
- udata/tests/helpers.py +2 -7
- udata/tests/metrics/test_metrics.py +52 -48
- udata/tests/metrics/test_tasks.py +154 -150
- udata/tests/organization/test_csv_adapter.py +2 -5
- udata/tests/organization/test_notifications.py +2 -4
- udata/tests/organization/test_organization_model.py +3 -4
- udata/tests/organization/test_organization_rdf.py +6 -12
- udata/tests/plugin.py +6 -110
- udata/tests/reuse/test_reuse_model.py +3 -4
- udata/tests/site/test_site_api.py +0 -2
- udata/tests/site/test_site_csv_exports.py +0 -2
- udata/tests/site/test_site_metrics.py +2 -4
- udata/tests/site/test_site_model.py +2 -2
- udata/tests/site/test_site_rdf.py +85 -29
- udata/tests/test_activity.py +3 -3
- udata/tests/test_api_fields.py +6 -9
- udata/tests/test_cors.py +0 -2
- udata/tests/test_dcat_commands.py +2 -3
- udata/tests/test_discussions.py +2 -7
- udata/tests/test_mail.py +150 -114
- udata/tests/test_migrations.py +413 -419
- udata/tests/test_model.py +10 -11
- udata/tests/test_notifications.py +2 -3
- udata/tests/test_owned.py +3 -3
- udata/tests/test_rdf.py +19 -15
- udata/tests/test_routing.py +5 -5
- udata/tests/test_storages.py +6 -5
- udata/tests/test_tags.py +2 -4
- udata/tests/test_topics.py +2 -4
- udata/tests/test_transfer.py +4 -5
- udata/tests/topic/test_topic_tasks.py +25 -27
- udata/tests/user/test_user_rdf.py +2 -8
- udata/tests/user/test_user_tasks.py +3 -5
- udata/tests/workers/test_jobs_commands.py +2 -2
- udata/tests/workers/test_tasks_routing.py +27 -27
- udata/translations/ar/LC_MESSAGES/udata.mo +0 -0
- udata/translations/ar/LC_MESSAGES/udata.po +369 -435
- udata/translations/de/LC_MESSAGES/udata.mo +0 -0
- udata/translations/de/LC_MESSAGES/udata.po +371 -437
- udata/translations/es/LC_MESSAGES/udata.mo +0 -0
- udata/translations/es/LC_MESSAGES/udata.po +369 -435
- udata/translations/fr/LC_MESSAGES/udata.mo +0 -0
- udata/translations/fr/LC_MESSAGES/udata.po +381 -447
- udata/translations/it/LC_MESSAGES/udata.mo +0 -0
- udata/translations/it/LC_MESSAGES/udata.po +371 -437
- udata/translations/pt/LC_MESSAGES/udata.mo +0 -0
- udata/translations/pt/LC_MESSAGES/udata.po +371 -437
- udata/translations/sr/LC_MESSAGES/udata.mo +0 -0
- udata/translations/sr/LC_MESSAGES/udata.po +372 -438
- udata/translations/udata.pot +379 -440
- udata/utils.py +66 -4
- {udata-12.0.2.dev10.dist-info → udata-13.0.1.dev21.dist-info}/METADATA +1 -4
- {udata-12.0.2.dev10.dist-info → udata-13.0.1.dev21.dist-info}/RECORD +212 -256
- udata/linkchecker/__init__.py +0 -0
- udata/linkchecker/backends.py +0 -31
- udata/linkchecker/checker.py +0 -75
- udata/linkchecker/commands.py +0 -21
- udata/linkchecker/models.py +0 -9
- udata/linkchecker/tasks.py +0 -55
- udata/templates/mail/account_deleted.html +0 -5
- udata/templates/mail/account_deleted.txt +0 -6
- udata/templates/mail/account_inactivity.html +0 -40
- udata/templates/mail/account_inactivity.txt +0 -31
- udata/templates/mail/badge_added_association.html +0 -33
- udata/templates/mail/badge_added_association.txt +0 -11
- udata/templates/mail/badge_added_certified.html +0 -33
- udata/templates/mail/badge_added_certified.txt +0 -11
- udata/templates/mail/badge_added_company.html +0 -33
- udata/templates/mail/badge_added_company.txt +0 -11
- udata/templates/mail/badge_added_local_authority.html +0 -33
- udata/templates/mail/badge_added_local_authority.txt +0 -11
- udata/templates/mail/badge_added_public_service.html +0 -33
- udata/templates/mail/badge_added_public_service.txt +0 -11
- udata/templates/mail/discussion_closed.html +0 -47
- udata/templates/mail/discussion_closed.txt +0 -16
- udata/templates/mail/inactive_account_deleted.html +0 -5
- udata/templates/mail/inactive_account_deleted.txt +0 -6
- udata/templates/mail/membership_refused.html +0 -20
- udata/templates/mail/membership_refused.txt +0 -11
- udata/templates/mail/membership_request.html +0 -46
- udata/templates/mail/membership_request.txt +0 -12
- udata/templates/mail/new_discussion.html +0 -44
- udata/templates/mail/new_discussion.txt +0 -15
- udata/templates/mail/new_discussion_comment.html +0 -45
- udata/templates/mail/new_discussion_comment.txt +0 -16
- udata/templates/mail/new_member.html +0 -27
- udata/templates/mail/new_member.txt +0 -11
- udata/templates/mail/new_reuse.html +0 -37
- udata/templates/mail/new_reuse.txt +0 -9
- udata/templates/mail/test.html +0 -6
- udata/templates/mail/test.txt +0 -6
- udata/templates/mail/user_mail_card.html +0 -26
- udata/templates/security/email/base.html +0 -105
- udata/templates/security/email/base.txt +0 -6
- udata/templates/security/email/button.html +0 -3
- udata/templates/security/email/change_notice.html +0 -22
- udata/templates/security/email/change_notice.txt +0 -8
- udata/templates/security/email/confirmation_instructions.html +0 -20
- udata/templates/security/email/confirmation_instructions.txt +0 -7
- udata/templates/security/email/login_instructions.html +0 -19
- udata/templates/security/email/login_instructions.txt +0 -7
- udata/templates/security/email/reset_instructions.html +0 -24
- udata/templates/security/email/reset_instructions.txt +0 -9
- udata/templates/security/email/reset_notice.html +0 -11
- udata/templates/security/email/reset_notice.txt +0 -4
- udata/templates/security/email/welcome.html +0 -24
- udata/templates/security/email/welcome.txt +0 -9
- udata/templates/security/email/welcome_existing.html +0 -32
- udata/templates/security/email/welcome_existing.txt +0 -14
- udata/terms.md +0 -6
- udata/tests/frontend/__init__.py +0 -23
- udata/tests/metrics/conftest.py +0 -15
- udata/tests/test_linkchecker.py +0 -277
- {udata-12.0.2.dev10.dist-info → udata-13.0.1.dev21.dist-info}/WHEEL +0 -0
- {udata-12.0.2.dev10.dist-info → udata-13.0.1.dev21.dist-info}/entry_points.txt +0 -0
- {udata-12.0.2.dev10.dist-info → udata-13.0.1.dev21.dist-info}/licenses/LICENSE +0 -0
- {udata-12.0.2.dev10.dist-info → udata-13.0.1.dev21.dist-info}/top_level.txt +0 -0
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import pytest
|
|
2
1
|
from flask import url_for
|
|
3
2
|
from werkzeug.test import TestResponse
|
|
4
3
|
|
|
@@ -11,12 +10,9 @@ from udata.core.topic.factories import TopicFactory
|
|
|
11
10
|
from udata.core.topic.models import Topic
|
|
12
11
|
from udata.core.user.factories import AdminFactory, UserFactory
|
|
13
12
|
from udata.mongo import db
|
|
13
|
+
from udata.tests.api import APITestCase
|
|
14
14
|
from udata.tests.helpers import assert200, assert400
|
|
15
15
|
|
|
16
|
-
pytestmark = [
|
|
17
|
-
pytest.mark.usefixtures("clean_db"),
|
|
18
|
-
]
|
|
19
|
-
|
|
20
16
|
|
|
21
17
|
class FakeDatasetActivity(Activity):
|
|
22
18
|
key = "fakeDataset"
|
|
@@ -33,26 +29,24 @@ class FakeTopicActivity(Activity):
|
|
|
33
29
|
related_to = db.ReferenceField(Topic, required=True)
|
|
34
30
|
|
|
35
31
|
|
|
36
|
-
class ActivityAPITest:
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
def test_activity_api_list(self, api) -> None:
|
|
32
|
+
class ActivityAPITest(APITestCase):
|
|
33
|
+
def test_activity_api_list(self) -> None:
|
|
40
34
|
"""It should fetch an activity list from the API"""
|
|
41
35
|
activities: list[Activity] = [
|
|
42
36
|
FakeDatasetActivity.objects.create(actor=UserFactory(), related_to=DatasetFactory()),
|
|
43
37
|
FakeReuseActivity.objects.create(actor=UserFactory(), related_to=ReuseFactory()),
|
|
44
38
|
]
|
|
45
39
|
|
|
46
|
-
response: TestResponse =
|
|
40
|
+
response: TestResponse = self.get(url_for("api.activity"))
|
|
47
41
|
assert200(response)
|
|
48
42
|
assert len(response.json["data"]) == len(activities)
|
|
49
43
|
|
|
50
|
-
def test_activity_api_list_filter_by_bogus_related_to(self
|
|
44
|
+
def test_activity_api_list_filter_by_bogus_related_to(self) -> None:
|
|
51
45
|
"""It should return a 400 error if the `related_to` parameter isn't a valid ObjectId."""
|
|
52
|
-
response: TestResponse =
|
|
46
|
+
response: TestResponse = self.get(url_for("api.activity", related_to="foobar"))
|
|
53
47
|
assert400(response)
|
|
54
48
|
|
|
55
|
-
def test_activity_api_list_filtered_by_related_to(self
|
|
49
|
+
def test_activity_api_list_filtered_by_related_to(self) -> None:
|
|
56
50
|
"""It should only return activities that correspond to the `related_to` parameter."""
|
|
57
51
|
dataset1: Dataset = DatasetFactory()
|
|
58
52
|
dataset2: Dataset = DatasetFactory()
|
|
@@ -64,18 +58,18 @@ class ActivityAPITest:
|
|
|
64
58
|
FakeReuseActivity.objects.create(actor=UserFactory(), related_to=reuse),
|
|
65
59
|
]
|
|
66
60
|
|
|
67
|
-
response: TestResponse =
|
|
61
|
+
response: TestResponse = self.get(url_for("api.activity", related_to=dataset1.id))
|
|
68
62
|
assert200(response)
|
|
69
63
|
len(response.json["data"]) == 2
|
|
70
64
|
assert response.json["data"][0]["related_to"] == dataset1.title
|
|
71
65
|
assert response.json["data"][1]["related_to"] == dataset1.title
|
|
72
66
|
|
|
73
|
-
response: TestResponse =
|
|
67
|
+
response: TestResponse = self.get(url_for("api.activity", related_to=reuse.id))
|
|
74
68
|
assert200(response)
|
|
75
69
|
len(response.json["data"]) == 1
|
|
76
70
|
assert response.json["data"][0]["related_to"] == reuse.title
|
|
77
71
|
|
|
78
|
-
def test_activity_api_list_with_private(self
|
|
72
|
+
def test_activity_api_list_with_private(self) -> None:
|
|
79
73
|
"""It should fetch an activity list from the API"""
|
|
80
74
|
activities: list[Activity] = [
|
|
81
75
|
FakeDatasetActivity.objects.create(
|
|
@@ -87,28 +81,28 @@ class ActivityAPITest:
|
|
|
87
81
|
]
|
|
88
82
|
|
|
89
83
|
# Anonymised user won't see activities about private documents
|
|
90
|
-
response: TestResponse =
|
|
84
|
+
response: TestResponse = self.get(url_for("api.activity"))
|
|
91
85
|
assert200(response)
|
|
92
86
|
assert len(response.json["data"]) == 0
|
|
93
87
|
|
|
94
88
|
# Lambda user won't see activities about private documents
|
|
95
|
-
|
|
96
|
-
response: TestResponse =
|
|
89
|
+
self.login()
|
|
90
|
+
response: TestResponse = self.get(url_for("api.activity"))
|
|
97
91
|
assert200(response)
|
|
98
92
|
assert len(response.json["data"]) == 0
|
|
99
93
|
|
|
100
94
|
# Sysadmin user will see activities about private documents
|
|
101
|
-
|
|
102
|
-
response: TestResponse =
|
|
95
|
+
self.login(AdminFactory())
|
|
96
|
+
response: TestResponse = self.get(url_for("api.activity"))
|
|
103
97
|
assert200(response)
|
|
104
98
|
assert len(response.json["data"]) == len(activities)
|
|
105
99
|
|
|
106
|
-
def test_activity_api_with_topic(self
|
|
100
|
+
def test_activity_api_with_topic(self) -> None:
|
|
107
101
|
"""It should fetch topic activities from the API"""
|
|
108
102
|
topic: Topic = TopicFactory()
|
|
109
103
|
FakeTopicActivity.objects.create(actor=UserFactory(), related_to=topic)
|
|
110
104
|
|
|
111
|
-
response: TestResponse =
|
|
105
|
+
response: TestResponse = self.get(url_for("api.activity"))
|
|
112
106
|
assert200(response)
|
|
113
107
|
assert len(response.json["data"]) == 1
|
|
114
108
|
|
udata/tests/api/test_auth_api.py
CHANGED
|
@@ -14,6 +14,7 @@ from udata.api.oauth2 import OAuth2Client, OAuth2Token
|
|
|
14
14
|
from udata.auth import PermissionDenied
|
|
15
15
|
from udata.core.user.factories import UserFactory
|
|
16
16
|
from udata.forms import Form, fields, validators
|
|
17
|
+
from udata.tests.api import PytestOnlyAPITestCase
|
|
17
18
|
from udata.tests.helpers import (
|
|
18
19
|
assert200,
|
|
19
20
|
assert400,
|
|
@@ -65,10 +66,7 @@ def oauth(app, request):
|
|
|
65
66
|
return OAuth2Client.objects.create(**kwargs)
|
|
66
67
|
|
|
67
68
|
|
|
68
|
-
|
|
69
|
-
class APIAuthTest:
|
|
70
|
-
modules = []
|
|
71
|
-
|
|
69
|
+
class APIAuthTest(PytestOnlyAPITestCase):
|
|
72
70
|
def test_no_auth(self, api):
|
|
73
71
|
"""Should not return a content type if there is no content on delete"""
|
|
74
72
|
response = api.get(url_for("api.fake"))
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import pytest
|
|
2
1
|
from flask import url_for
|
|
3
2
|
|
|
4
3
|
from udata.core.contact_point.factories import ContactPointFactory
|
|
@@ -7,17 +6,12 @@ from udata.core.organization.factories import OrganizationFactory
|
|
|
7
6
|
from udata.core.organization.models import Member
|
|
8
7
|
from udata.i18n import gettext as _
|
|
9
8
|
from udata.models import ContactPoint
|
|
9
|
+
from udata.tests.api import APITestCase
|
|
10
10
|
from udata.tests.helpers import assert200, assert201, assert204, assert400, assert403
|
|
11
11
|
from udata.utils import faker
|
|
12
12
|
|
|
13
|
-
pytestmark = [
|
|
14
|
-
pytest.mark.usefixtures("clean_db"),
|
|
15
|
-
]
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
class ContactPointAPITest:
|
|
19
|
-
modules = []
|
|
20
13
|
|
|
14
|
+
class ContactPointAPITest(APITestCase):
|
|
21
15
|
def test_get_or_create(self):
|
|
22
16
|
org = OrganizationFactory()
|
|
23
17
|
contact_point, created = ContactPoint.objects().get_or_create(
|
|
@@ -51,46 +45,46 @@ class ContactPointAPITest:
|
|
|
51
45
|
assert created
|
|
52
46
|
assert contact_point.name == "Another"
|
|
53
47
|
|
|
54
|
-
def test_contact_point_api_create(self
|
|
55
|
-
user =
|
|
48
|
+
def test_contact_point_api_create(self):
|
|
49
|
+
user = self.login()
|
|
56
50
|
data = {
|
|
57
51
|
"name": faker.word(),
|
|
58
52
|
"email": faker.email(),
|
|
59
53
|
"contact_form": faker.url(),
|
|
60
54
|
"role": "contact",
|
|
61
55
|
}
|
|
62
|
-
response =
|
|
56
|
+
response = self.post(url_for("api.contact_points"), data=data)
|
|
63
57
|
assert201(response)
|
|
64
58
|
assert ContactPoint.objects.count() == 1
|
|
65
59
|
|
|
66
60
|
contact_point = ContactPoint.objects.first()
|
|
67
61
|
assert contact_point.owner.id == user.id
|
|
68
62
|
|
|
69
|
-
def test_contact_point_api_create_email_or_contact_form(self
|
|
70
|
-
|
|
63
|
+
def test_contact_point_api_create_email_or_contact_form(self):
|
|
64
|
+
self.login()
|
|
71
65
|
data = {"name": faker.word(), "contact_form": faker.url(), "role": "contact"}
|
|
72
|
-
response =
|
|
66
|
+
response = self.post(url_for("api.contact_points"), data=data)
|
|
73
67
|
assert201(response)
|
|
74
68
|
assert ContactPoint.objects.count() == 1
|
|
75
69
|
|
|
76
70
|
data = {"name": faker.word(), "email": faker.email(), "role": "contact"}
|
|
77
|
-
response =
|
|
71
|
+
response = self.post(url_for("api.contact_points"), data=data)
|
|
78
72
|
assert201(response)
|
|
79
73
|
assert ContactPoint.objects.count() == 2
|
|
80
74
|
|
|
81
|
-
def test_contact_point_duplicate_creation(self
|
|
82
|
-
|
|
75
|
+
def test_contact_point_duplicate_creation(self):
|
|
76
|
+
self.login()
|
|
83
77
|
data = {"name": faker.word(), "contact_form": faker.url(), "role": "contact"}
|
|
84
|
-
response =
|
|
78
|
+
response = self.post(url_for("api.contact_points"), data=data)
|
|
85
79
|
assert201(response)
|
|
86
80
|
assert ContactPoint.objects.count() == 1
|
|
87
81
|
|
|
88
|
-
response =
|
|
82
|
+
response = self.post(url_for("api.contact_points"), data=data)
|
|
89
83
|
assert200(response)
|
|
90
84
|
assert ContactPoint.objects.count() == 1
|
|
91
85
|
|
|
92
|
-
def test_contact_point_for_different_org(self
|
|
93
|
-
user =
|
|
86
|
+
def test_contact_point_for_different_org(self):
|
|
87
|
+
user = self.login()
|
|
94
88
|
member = Member(user=user, role="editor")
|
|
95
89
|
org_a = OrganizationFactory(members=[member])
|
|
96
90
|
|
|
@@ -100,11 +94,11 @@ class ContactPointAPITest:
|
|
|
100
94
|
"role": "contact",
|
|
101
95
|
"organization": str(org_a.id),
|
|
102
96
|
}
|
|
103
|
-
response =
|
|
97
|
+
response = self.post(url_for("api.contact_points"), data=data)
|
|
104
98
|
assert201(response)
|
|
105
99
|
assert ContactPoint.objects.count() == 1
|
|
106
100
|
|
|
107
|
-
response =
|
|
101
|
+
response = self.post(url_for("api.contact_points"), data=data)
|
|
108
102
|
assert200(response)
|
|
109
103
|
assert ContactPoint.objects.count() == 1
|
|
110
104
|
|
|
@@ -114,39 +108,39 @@ class ContactPointAPITest:
|
|
|
114
108
|
|
|
115
109
|
org_b = OrganizationFactory(members=[])
|
|
116
110
|
data["organization"] = str(org_b.id)
|
|
117
|
-
response =
|
|
111
|
+
response = self.post(url_for("api.contact_points"), data=data)
|
|
118
112
|
assert400(response)
|
|
119
113
|
assert ContactPoint.objects.count() == 1
|
|
120
114
|
|
|
121
115
|
org_b.members = [Member(user=user, role="editor")]
|
|
122
116
|
org_b.save()
|
|
123
117
|
|
|
124
|
-
response =
|
|
118
|
+
response = self.post(url_for("api.contact_points"), data=data)
|
|
125
119
|
assert201(response)
|
|
126
120
|
assert ContactPoint.objects.count() == 2
|
|
127
121
|
|
|
128
|
-
def test_contact_point_api_invalid_email(self
|
|
129
|
-
|
|
122
|
+
def test_contact_point_api_invalid_email(self):
|
|
123
|
+
self.login()
|
|
130
124
|
data = {"name": faker.word(), "email": faker.word(), "role": "contact"}
|
|
131
|
-
response =
|
|
125
|
+
response = self.post(url_for("api.contact_points"), data=data)
|
|
132
126
|
assert400(response)
|
|
133
127
|
assert "email" in response.json["errors"]
|
|
134
128
|
assert ContactPoint.objects.count() == 0
|
|
135
129
|
|
|
136
|
-
def test_contact_point_missing_contact_information(self
|
|
137
|
-
|
|
130
|
+
def test_contact_point_missing_contact_information(self):
|
|
131
|
+
self.login()
|
|
138
132
|
data = {"name": faker.word(), "role": "contact"}
|
|
139
|
-
response =
|
|
133
|
+
response = self.post(url_for("api.contact_points"), data=data)
|
|
140
134
|
assert400(response)
|
|
141
135
|
assert response.json["message"] == _(
|
|
142
136
|
"At least an email or a contact form is required for a contact point"
|
|
143
137
|
)
|
|
144
138
|
assert ContactPoint.objects.count() == 0
|
|
145
139
|
|
|
146
|
-
def test_contact_point_missing_role(self
|
|
147
|
-
|
|
140
|
+
def test_contact_point_missing_role(self):
|
|
141
|
+
self.login()
|
|
148
142
|
data = {"name": faker.word(), "email": faker.email()}
|
|
149
|
-
response =
|
|
143
|
+
response = self.post(url_for("api.contact_points"), data=data)
|
|
150
144
|
assert400(response)
|
|
151
145
|
assert (
|
|
152
146
|
response.json["message"]
|
|
@@ -154,70 +148,70 @@ class ContactPointAPITest:
|
|
|
154
148
|
)
|
|
155
149
|
assert ContactPoint.objects.count() == 0
|
|
156
150
|
|
|
157
|
-
def test_contact_point_no_need_for_email_for_role_other_than_contact(self
|
|
158
|
-
|
|
151
|
+
def test_contact_point_no_need_for_email_for_role_other_than_contact(self):
|
|
152
|
+
self.login()
|
|
159
153
|
roles_other_than_contact = [role_ for role_ in CONTACT_ROLES.keys() if role_ != "contact"]
|
|
160
154
|
for index, role in enumerate(roles_other_than_contact):
|
|
161
155
|
data = {"name": faker.word(), "role": role}
|
|
162
|
-
response =
|
|
156
|
+
response = self.post(url_for("api.contact_points"), data=data)
|
|
163
157
|
assert201(response)
|
|
164
158
|
assert ContactPoint.objects.count() == index + 1
|
|
165
159
|
|
|
166
|
-
def test_contact_point_api_update(self
|
|
167
|
-
user =
|
|
160
|
+
def test_contact_point_api_update(self):
|
|
161
|
+
user = self.login()
|
|
168
162
|
member = Member(user=user, role="editor")
|
|
169
163
|
org = OrganizationFactory(members=[member])
|
|
170
164
|
contact_point = ContactPointFactory(organization=org)
|
|
171
165
|
data = contact_point.to_dict()
|
|
172
166
|
data["email"] = "new.email@newdomain.com"
|
|
173
|
-
response =
|
|
167
|
+
response = self.put(url_for("api.contact_point", contact_point=contact_point), data)
|
|
174
168
|
assert200(response)
|
|
175
169
|
assert ContactPoint.objects.count() == 1
|
|
176
170
|
assert ContactPoint.objects.first().email == "new.email@newdomain.com"
|
|
177
171
|
|
|
178
|
-
def test_contact_point_api_update_to_existing_contact_point(self
|
|
179
|
-
user =
|
|
172
|
+
def test_contact_point_api_update_to_existing_contact_point(self):
|
|
173
|
+
user = self.login()
|
|
180
174
|
contact_point_a = ContactPointFactory(email="a@example.org", owner=user)
|
|
181
175
|
contact_point_b = ContactPointFactory(email="b@example.org", owner=user)
|
|
182
176
|
|
|
183
177
|
data_b = contact_point_b.to_dict()
|
|
184
|
-
response =
|
|
178
|
+
response = self.put(url_for("api.contact_point", contact_point=contact_point_a), data_b)
|
|
185
179
|
assert400(response)
|
|
186
180
|
assert ContactPoint.objects.count() == 2
|
|
187
181
|
|
|
188
182
|
contact_point_a.reload()
|
|
189
183
|
assert contact_point_a.email == "a@example.org"
|
|
190
184
|
|
|
191
|
-
def test_contact_point_api_update_forbidden(self
|
|
192
|
-
|
|
185
|
+
def test_contact_point_api_update_forbidden(self):
|
|
186
|
+
self.login()
|
|
193
187
|
org = OrganizationFactory()
|
|
194
188
|
contact_point = ContactPointFactory(organization=org)
|
|
195
189
|
data = contact_point.to_dict()
|
|
196
190
|
data["email"] = "new.email@newdomain.com"
|
|
197
|
-
response =
|
|
191
|
+
response = self.put(url_for("api.contact_point", contact_point=contact_point), data)
|
|
198
192
|
assert403(response)
|
|
199
193
|
assert ContactPoint.objects.count() == 1
|
|
200
194
|
assert ContactPoint.objects.first().email == contact_point.email
|
|
201
195
|
|
|
202
|
-
def test_contact_point_api_delete(self
|
|
203
|
-
user =
|
|
196
|
+
def test_contact_point_api_delete(self):
|
|
197
|
+
user = self.login()
|
|
204
198
|
member = Member(user=user, role="editor")
|
|
205
199
|
org = OrganizationFactory(members=[member])
|
|
206
200
|
contact_point = ContactPointFactory(organization=org)
|
|
207
|
-
response =
|
|
201
|
+
response = self.delete(url_for("api.contact_point", contact_point=contact_point))
|
|
208
202
|
assert204(response)
|
|
209
203
|
assert ContactPoint.objects.count() == 0
|
|
210
204
|
|
|
211
|
-
def test_contact_point_roles_list(self
|
|
205
|
+
def test_contact_point_roles_list(self):
|
|
212
206
|
"""It should fetch the contact point roles list from the API"""
|
|
213
|
-
response =
|
|
207
|
+
response = self.get(url_for("api.contact_point_roles"))
|
|
214
208
|
assert200(response)
|
|
215
209
|
assert len(response.json) == len(CONTACT_ROLES)
|
|
216
210
|
|
|
217
|
-
def test_contact_point_api_delete_forbidden(self
|
|
218
|
-
|
|
211
|
+
def test_contact_point_api_delete_forbidden(self):
|
|
212
|
+
self.login()
|
|
219
213
|
org = OrganizationFactory()
|
|
220
214
|
contact_point = ContactPointFactory(organization=org)
|
|
221
|
-
response =
|
|
215
|
+
response = self.delete(url_for("api.contact_point", contact_point=contact_point))
|
|
222
216
|
assert403(response)
|
|
223
217
|
assert ContactPoint.objects.count() == 1
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
from datetime import datetime, timedelta
|
|
2
|
-
from xml.etree.ElementTree import XML
|
|
3
2
|
|
|
4
3
|
import feedparser
|
|
5
4
|
import pytest
|
|
@@ -7,24 +6,20 @@ from flask import url_for
|
|
|
7
6
|
from werkzeug.test import TestResponse
|
|
8
7
|
|
|
9
8
|
import udata.core.organization.constants as org_constants
|
|
10
|
-
from udata.core.
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
DATASERVICE_ACCESS_AUDIENCE_YES,
|
|
15
|
-
DATASERVICE_ACCESS_TYPE_OPEN,
|
|
16
|
-
DATASERVICE_ACCESS_TYPE_OPEN_WITH_ACCOUNT,
|
|
17
|
-
DATASERVICE_ACCESS_TYPE_RESTRICTED,
|
|
9
|
+
from udata.core.access_type.constants import (
|
|
10
|
+
AccessAudienceCondition,
|
|
11
|
+
AccessAudienceType,
|
|
12
|
+
AccessType,
|
|
18
13
|
)
|
|
19
14
|
from udata.core.dataservices.factories import DataserviceFactory
|
|
20
15
|
from udata.core.dataservices.models import Dataservice
|
|
21
16
|
from udata.core.dataset.factories import DatasetFactory, LicenseFactory
|
|
22
17
|
from udata.core.organization.factories import OrganizationFactory
|
|
23
18
|
from udata.core.organization.models import Member
|
|
24
|
-
from udata.core.topic.factories import TopicElementFactory, TopicFactory
|
|
19
|
+
from udata.core.topic.factories import ReuseFactory, TopicElementFactory, TopicFactory
|
|
25
20
|
from udata.core.user.factories import AdminFactory, UserFactory
|
|
26
21
|
from udata.i18n import gettext as _
|
|
27
|
-
from udata.tests.helpers import assert200, assert400, assert410
|
|
22
|
+
from udata.tests.helpers import assert200, assert400, assert410
|
|
28
23
|
|
|
29
24
|
from . import APITestCase
|
|
30
25
|
|
|
@@ -35,8 +30,6 @@ def dataservice_in_response(response: TestResponse, dataservice: Dataservice) ->
|
|
|
35
30
|
|
|
36
31
|
|
|
37
32
|
class DataserviceAPITest(APITestCase):
|
|
38
|
-
modules = []
|
|
39
|
-
|
|
40
33
|
def test_dataservice_api_get(self):
|
|
41
34
|
"""It should fetch a dataservice from the API"""
|
|
42
35
|
dataservice = DataserviceFactory()
|
|
@@ -106,6 +99,34 @@ class DataserviceAPITest(APITestCase):
|
|
|
106
99
|
assert len(response.json["data"]) == 1
|
|
107
100
|
assert response.json["data"][0]["id"] == str(topic_dataservice.id)
|
|
108
101
|
|
|
102
|
+
# filter on reuse
|
|
103
|
+
reuse_dataservice = DataserviceFactory()
|
|
104
|
+
reuse = ReuseFactory(dataservices=[reuse_dataservice])
|
|
105
|
+
response = self.get(url_for("api.dataservices", reuse=reuse.id))
|
|
106
|
+
assert200(response)
|
|
107
|
+
assert len(response.json["data"]) == 1
|
|
108
|
+
assert response.json["data"][0]["id"] == str(reuse_dataservice.id)
|
|
109
|
+
|
|
110
|
+
def test_dataservices_topic_filter_errors(self):
|
|
111
|
+
# non-existing
|
|
112
|
+
response = self.get(url_for("api.dataservices", topic="690c7f48ec85adaa376c1e93"))
|
|
113
|
+
assert200(response)
|
|
114
|
+
|
|
115
|
+
# not an object ID
|
|
116
|
+
response = self.get(url_for("api.dataservices", topic="xxx"))
|
|
117
|
+
assert400(response)
|
|
118
|
+
assert "`topic` must be an identifier" in response.json["message"]
|
|
119
|
+
|
|
120
|
+
def test_dataservices_reuse_filter_errors(self):
|
|
121
|
+
# non-existing
|
|
122
|
+
response = self.get(url_for("api.dataservices", reuse="690c7f48ec85adaa376c1e93"))
|
|
123
|
+
assert200(response)
|
|
124
|
+
|
|
125
|
+
# not an object ID
|
|
126
|
+
response = self.get(url_for("api.dataservices", reuse="xxx"))
|
|
127
|
+
assert400(response)
|
|
128
|
+
assert "`reuse` must be an identifier" in response.json["message"]
|
|
129
|
+
|
|
109
130
|
def test_dataservice_api_create(self):
|
|
110
131
|
user = self.login()
|
|
111
132
|
datasets = DatasetFactory.create_batch(3)
|
|
@@ -141,15 +162,15 @@ class DataserviceAPITest(APITestCase):
|
|
|
141
162
|
"extras": {
|
|
142
163
|
"foo": "bar",
|
|
143
164
|
},
|
|
144
|
-
"access_type":
|
|
165
|
+
"access_type": AccessType.RESTRICTED,
|
|
145
166
|
"access_audiences": [
|
|
146
167
|
{
|
|
147
|
-
"role":
|
|
148
|
-
"condition":
|
|
168
|
+
"role": AccessAudienceType.ADMINISTRATION,
|
|
169
|
+
"condition": AccessAudienceCondition.YES,
|
|
149
170
|
},
|
|
150
171
|
{
|
|
151
|
-
"role":
|
|
152
|
-
"condition":
|
|
172
|
+
"role": AccessAudienceType.COMPANY,
|
|
173
|
+
"condition": AccessAudienceCondition.UNDER_CONDITIONS,
|
|
153
174
|
},
|
|
154
175
|
],
|
|
155
176
|
},
|
|
@@ -165,20 +186,18 @@ class DataserviceAPITest(APITestCase):
|
|
|
165
186
|
self.assertEqual(
|
|
166
187
|
response.json["self_api_url"], "http://local.test/api/1/dataservices/updated-title/"
|
|
167
188
|
)
|
|
168
|
-
self.assertEqual(response.json["access_type"],
|
|
189
|
+
self.assertEqual(response.json["access_type"], AccessType.RESTRICTED)
|
|
169
190
|
self.assertEqual(len(response.json["access_audiences"]), 2)
|
|
170
191
|
self.assertEqual(
|
|
171
|
-
response.json["access_audiences"][0]["role"],
|
|
192
|
+
response.json["access_audiences"][0]["role"], AccessAudienceType.ADMINISTRATION
|
|
172
193
|
)
|
|
173
194
|
self.assertEqual(
|
|
174
|
-
response.json["access_audiences"][0]["condition"],
|
|
175
|
-
)
|
|
176
|
-
self.assertEqual(
|
|
177
|
-
response.json["access_audiences"][1]["role"], DATASERVICE_ACCESS_AUDIENCE_COMPANY
|
|
195
|
+
response.json["access_audiences"][0]["condition"], AccessAudienceCondition.YES
|
|
178
196
|
)
|
|
197
|
+
self.assertEqual(response.json["access_audiences"][1]["role"], AccessAudienceType.COMPANY)
|
|
179
198
|
self.assertEqual(
|
|
180
199
|
response.json["access_audiences"][1]["condition"],
|
|
181
|
-
|
|
200
|
+
AccessAudienceCondition.UNDER_CONDITIONS,
|
|
182
201
|
)
|
|
183
202
|
# metadata_modified_at should have been updated during the patch
|
|
184
203
|
self.assertNotEqual(
|
|
@@ -327,7 +346,7 @@ class DataserviceAPITest(APITestCase):
|
|
|
327
346
|
"title": "B",
|
|
328
347
|
"base_api_url": "https://example.org/B",
|
|
329
348
|
"datasets": [dataset_b.id],
|
|
330
|
-
"access_type":
|
|
349
|
+
"access_type": AccessType.OPEN,
|
|
331
350
|
},
|
|
332
351
|
)
|
|
333
352
|
self.post(
|
|
@@ -336,7 +355,7 @@ class DataserviceAPITest(APITestCase):
|
|
|
336
355
|
"title": "C",
|
|
337
356
|
"base_api_url": "https://example.org/C",
|
|
338
357
|
"datasets": [dataset_a.id, dataset_b.id],
|
|
339
|
-
"access_type":
|
|
358
|
+
"access_type": AccessType.OPEN_WITH_ACCOUNT,
|
|
340
359
|
},
|
|
341
360
|
)
|
|
342
361
|
self.post(
|
|
@@ -345,7 +364,7 @@ class DataserviceAPITest(APITestCase):
|
|
|
345
364
|
"title": "A",
|
|
346
365
|
"base_api_url": "https://example.org/A",
|
|
347
366
|
"datasets": [dataset_a.id],
|
|
348
|
-
"access_type":
|
|
367
|
+
"access_type": AccessType.RESTRICTED,
|
|
349
368
|
},
|
|
350
369
|
)
|
|
351
370
|
self.post(
|
|
@@ -408,7 +427,7 @@ class DataserviceAPITest(APITestCase):
|
|
|
408
427
|
self.assertEqual(response.json["data"][0]["title"], "A")
|
|
409
428
|
self.assertEqual(response.json["data"][1]["title"], "C")
|
|
410
429
|
|
|
411
|
-
response = self.get(url_for("api.dataservices", access_type=
|
|
430
|
+
response = self.get(url_for("api.dataservices", access_type=AccessType.OPEN))
|
|
412
431
|
self.assert200(response)
|
|
413
432
|
|
|
414
433
|
print(response.json)
|
|
@@ -599,15 +618,15 @@ class DataserviceAPITest(APITestCase):
|
|
|
599
618
|
{
|
|
600
619
|
"title": "My title",
|
|
601
620
|
"base_api_url": "https://example.org",
|
|
602
|
-
"access_type":
|
|
621
|
+
"access_type": AccessType.RESTRICTED,
|
|
603
622
|
"access_audiences": [
|
|
604
623
|
{
|
|
605
|
-
"role":
|
|
606
|
-
"condition":
|
|
624
|
+
"role": AccessAudienceType.ADMINISTRATION,
|
|
625
|
+
"condition": AccessAudienceCondition.YES,
|
|
607
626
|
},
|
|
608
627
|
{
|
|
609
|
-
"role":
|
|
610
|
-
"condition":
|
|
628
|
+
"role": AccessAudienceType.ADMINISTRATION,
|
|
629
|
+
"condition": AccessAudienceCondition.UNDER_CONDITIONS,
|
|
611
630
|
},
|
|
612
631
|
],
|
|
613
632
|
},
|
|
@@ -623,15 +642,15 @@ class DataserviceAPITest(APITestCase):
|
|
|
623
642
|
dataservice = DataserviceFactory(owner=user, organization=original_org)
|
|
624
643
|
|
|
625
644
|
data = dataservice.to_dict()
|
|
626
|
-
data["access_type"] =
|
|
645
|
+
data["access_type"] = AccessType.RESTRICTED
|
|
627
646
|
data["access_audiences"] = [
|
|
628
647
|
{
|
|
629
|
-
"role":
|
|
630
|
-
"condition":
|
|
648
|
+
"role": AccessAudienceType.ADMINISTRATION,
|
|
649
|
+
"condition": AccessAudienceCondition.YES,
|
|
631
650
|
},
|
|
632
651
|
{
|
|
633
|
-
"role":
|
|
634
|
-
"condition":
|
|
652
|
+
"role": AccessAudienceType.ADMINISTRATION,
|
|
653
|
+
"condition": AccessAudienceCondition.UNDER_CONDITIONS,
|
|
635
654
|
},
|
|
636
655
|
]
|
|
637
656
|
response = self.patch(url_for("api.dataservice", dataservice=dataservice), data)
|
|
@@ -664,62 +683,10 @@ class DataserviceAPITest(APITestCase):
|
|
|
664
683
|
self.assertEqual(Dataservice.objects.first().organization.id, new_org.id)
|
|
665
684
|
|
|
666
685
|
|
|
667
|
-
@pytest.mark.frontend
|
|
668
|
-
class DataserviceRdfViewsTest:
|
|
669
|
-
def test_rdf_default_to_jsonld(self, client):
|
|
670
|
-
dataservice = DataserviceFactory()
|
|
671
|
-
expected = url_for("api.dataservice_rdf_format", dataservice=dataservice.id, format="json")
|
|
672
|
-
response = client.get(url_for("api.dataservice_rdf", dataservice=dataservice))
|
|
673
|
-
assert_redirects(response, expected)
|
|
674
|
-
|
|
675
|
-
def test_rdf_perform_content_negociation(self, client):
|
|
676
|
-
dataservice = DataserviceFactory()
|
|
677
|
-
expected = url_for("api.dataservice_rdf_format", dataservice=dataservice.id, format="xml")
|
|
678
|
-
url = url_for("api.dataservice_rdf", dataservice=dataservice)
|
|
679
|
-
headers = {"accept": "application/xml"}
|
|
680
|
-
response = client.get(url, headers=headers)
|
|
681
|
-
assert_redirects(response, expected)
|
|
682
|
-
|
|
683
|
-
def test_rdf_perform_content_negociation_response(self, client):
|
|
684
|
-
"""Check we have valid XML as output"""
|
|
685
|
-
dataservice = DataserviceFactory()
|
|
686
|
-
url = url_for("api.dataservice_rdf", dataservice=dataservice)
|
|
687
|
-
headers = {"accept": "application/xml"}
|
|
688
|
-
response = client.get(url, headers=headers, follow_redirects=True)
|
|
689
|
-
element = XML(response.data)
|
|
690
|
-
assert element.tag == "{http://www.w3.org/1999/02/22-rdf-syntax-ns#}RDF"
|
|
691
|
-
|
|
692
|
-
def test_dataservice_rdf_json_ld(self, client):
|
|
693
|
-
dataservice = DataserviceFactory()
|
|
694
|
-
for fmt in "json", "jsonld":
|
|
695
|
-
url = url_for("api.dataservice_rdf_format", dataservice=dataservice, format=fmt)
|
|
696
|
-
response = client.get(url, headers={"Accept": "application/ld+json"})
|
|
697
|
-
assert200(response)
|
|
698
|
-
assert response.content_type == "application/ld+json"
|
|
699
|
-
assert response.json["@context"]["@vocab"] == "http://www.w3.org/ns/dcat#"
|
|
700
|
-
|
|
701
|
-
@pytest.mark.parametrize(
|
|
702
|
-
"fmt,mime",
|
|
703
|
-
[
|
|
704
|
-
("n3", "text/n3"),
|
|
705
|
-
("nt", "application/n-triples"),
|
|
706
|
-
("ttl", "application/x-turtle"),
|
|
707
|
-
("xml", "application/rdf+xml"),
|
|
708
|
-
("rdf", "application/rdf+xml"),
|
|
709
|
-
("owl", "application/rdf+xml"),
|
|
710
|
-
("trig", "application/trig"),
|
|
711
|
-
],
|
|
712
|
-
)
|
|
713
|
-
def test_dataservice_rdf_formats(self, client, fmt, mime):
|
|
714
|
-
dataservice = DataserviceFactory()
|
|
715
|
-
url = url_for("api.dataservice_rdf_format", dataservice=dataservice, format=fmt)
|
|
716
|
-
response = client.get(url, headers={"Accept": mime})
|
|
717
|
-
assert200(response)
|
|
718
|
-
assert response.content_type == mime
|
|
719
|
-
|
|
720
|
-
|
|
721
686
|
class DataservicesFeedAPItest(APITestCase):
|
|
687
|
+
@pytest.mark.options(DELAY_BEFORE_APPEARING_IN_RSS_FEED=10)
|
|
722
688
|
def test_recent_feed(self):
|
|
689
|
+
# We have a 10 hours delay for a new object to appear in feed. A newly created one shouldn't appear.
|
|
723
690
|
DataserviceFactory(title="A", created_at=datetime.utcnow())
|
|
724
691
|
DataserviceFactory(title="B", created_at=datetime.utcnow() - timedelta(days=2))
|
|
725
692
|
DataserviceFactory(title="C", created_at=datetime.utcnow() - timedelta(days=1))
|
|
@@ -729,11 +696,11 @@ class DataservicesFeedAPItest(APITestCase):
|
|
|
729
696
|
|
|
730
697
|
feed = feedparser.parse(response.data)
|
|
731
698
|
|
|
732
|
-
self.assertEqual(len(feed.entries),
|
|
733
|
-
self.assertEqual(feed.entries[0].title, "
|
|
734
|
-
self.assertEqual(feed.entries[1].title, "
|
|
735
|
-
self.assertEqual(feed.entries[2].title, "B")
|
|
699
|
+
self.assertEqual(len(feed.entries), 2)
|
|
700
|
+
self.assertEqual(feed.entries[0].title, "C")
|
|
701
|
+
self.assertEqual(feed.entries[1].title, "B")
|
|
736
702
|
|
|
703
|
+
@pytest.mark.options(DELAY_BEFORE_APPEARING_IN_RSS_FEED=0)
|
|
737
704
|
def test_recent_feed_owner(self):
|
|
738
705
|
owner = UserFactory()
|
|
739
706
|
DataserviceFactory(owner=owner)
|
|
@@ -751,6 +718,7 @@ class DataservicesFeedAPItest(APITestCase):
|
|
|
751
718
|
self.assertEqual(author.name, owner.fullname)
|
|
752
719
|
self.assertEqual(author.href, owner.url_for())
|
|
753
720
|
|
|
721
|
+
@pytest.mark.options(DELAY_BEFORE_APPEARING_IN_RSS_FEED=0)
|
|
754
722
|
def test_recent_feed_org(self):
|
|
755
723
|
owner = UserFactory()
|
|
756
724
|
org = OrganizationFactory()
|