udata 9.1.2.dev30355__py2.py3-none-any.whl → 9.1.2.dev30454__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/__init__.py +109 -107
- tasks/helpers.py +18 -18
- udata/__init__.py +4 -4
- udata/admin/views.py +5 -5
- udata/api/__init__.py +111 -134
- udata/api/commands.py +45 -37
- udata/api/errors.py +5 -4
- udata/api/fields.py +23 -21
- udata/api/oauth2.py +55 -74
- udata/api/parsers.py +15 -15
- udata/api/signals.py +1 -1
- udata/api_fields.py +137 -89
- udata/app.py +58 -55
- udata/assets.py +5 -5
- udata/auth/__init__.py +37 -26
- udata/auth/forms.py +23 -15
- udata/auth/helpers.py +1 -1
- udata/auth/mails.py +3 -3
- udata/auth/password_validation.py +19 -15
- udata/auth/views.py +94 -68
- udata/commands/__init__.py +71 -69
- udata/commands/cache.py +7 -7
- udata/commands/db.py +201 -140
- udata/commands/dcat.py +36 -30
- udata/commands/fixtures.py +100 -84
- udata/commands/images.py +21 -20
- udata/commands/info.py +17 -20
- udata/commands/init.py +10 -10
- udata/commands/purge.py +12 -13
- udata/commands/serve.py +41 -29
- udata/commands/static.py +16 -18
- udata/commands/test.py +20 -20
- udata/commands/tests/fixtures.py +26 -24
- udata/commands/worker.py +31 -33
- udata/core/__init__.py +12 -12
- udata/core/activity/__init__.py +0 -1
- udata/core/activity/api.py +59 -49
- udata/core/activity/models.py +28 -26
- udata/core/activity/signals.py +1 -1
- udata/core/activity/tasks.py +16 -10
- udata/core/badges/api.py +6 -6
- udata/core/badges/commands.py +14 -13
- udata/core/badges/fields.py +8 -5
- udata/core/badges/forms.py +7 -4
- udata/core/badges/models.py +16 -31
- udata/core/badges/permissions.py +1 -3
- udata/core/badges/signals.py +2 -2
- udata/core/badges/tasks.py +3 -2
- udata/core/badges/tests/test_commands.py +10 -10
- udata/core/badges/tests/test_model.py +24 -31
- udata/core/contact_point/api.py +19 -18
- udata/core/contact_point/api_fields.py +21 -14
- udata/core/contact_point/factories.py +2 -2
- udata/core/contact_point/forms.py +7 -6
- udata/core/contact_point/models.py +3 -5
- udata/core/dataservices/api.py +26 -21
- udata/core/dataservices/factories.py +13 -11
- udata/core/dataservices/models.py +35 -40
- udata/core/dataservices/permissions.py +4 -4
- udata/core/dataservices/rdf.py +40 -17
- udata/core/dataservices/tasks.py +4 -3
- udata/core/dataset/actions.py +10 -10
- udata/core/dataset/activities.py +21 -23
- udata/core/dataset/api.py +321 -298
- udata/core/dataset/api_fields.py +443 -271
- udata/core/dataset/apiv2.py +305 -229
- udata/core/dataset/commands.py +38 -36
- udata/core/dataset/constants.py +61 -54
- udata/core/dataset/csv.py +70 -74
- udata/core/dataset/events.py +39 -32
- udata/core/dataset/exceptions.py +8 -4
- udata/core/dataset/factories.py +57 -65
- udata/core/dataset/forms.py +87 -63
- udata/core/dataset/models.py +336 -280
- udata/core/dataset/permissions.py +9 -6
- udata/core/dataset/preview.py +15 -17
- udata/core/dataset/rdf.py +156 -122
- udata/core/dataset/search.py +92 -77
- udata/core/dataset/signals.py +1 -1
- udata/core/dataset/tasks.py +63 -54
- udata/core/discussions/actions.py +5 -5
- udata/core/discussions/api.py +124 -120
- udata/core/discussions/factories.py +2 -2
- udata/core/discussions/forms.py +9 -7
- udata/core/discussions/metrics.py +1 -3
- udata/core/discussions/models.py +25 -24
- udata/core/discussions/notifications.py +18 -14
- udata/core/discussions/permissions.py +3 -3
- udata/core/discussions/signals.py +4 -4
- udata/core/discussions/tasks.py +24 -28
- udata/core/followers/api.py +32 -33
- udata/core/followers/models.py +9 -9
- udata/core/followers/signals.py +3 -3
- udata/core/jobs/actions.py +7 -7
- udata/core/jobs/api.py +99 -92
- udata/core/jobs/commands.py +48 -49
- udata/core/jobs/forms.py +11 -11
- udata/core/jobs/models.py +6 -6
- udata/core/metrics/__init__.py +2 -2
- udata/core/metrics/commands.py +34 -30
- udata/core/metrics/models.py +2 -4
- udata/core/metrics/signals.py +1 -1
- udata/core/metrics/tasks.py +3 -3
- udata/core/organization/activities.py +12 -15
- udata/core/organization/api.py +167 -174
- udata/core/organization/api_fields.py +183 -124
- udata/core/organization/apiv2.py +32 -32
- udata/core/organization/commands.py +20 -22
- udata/core/organization/constants.py +11 -11
- udata/core/organization/csv.py +17 -15
- udata/core/organization/factories.py +8 -11
- udata/core/organization/forms.py +32 -26
- udata/core/organization/metrics.py +2 -1
- udata/core/organization/models.py +87 -67
- udata/core/organization/notifications.py +18 -14
- udata/core/organization/permissions.py +10 -11
- udata/core/organization/rdf.py +14 -14
- udata/core/organization/search.py +30 -28
- udata/core/organization/signals.py +7 -7
- udata/core/organization/tasks.py +42 -61
- udata/core/owned.py +38 -27
- udata/core/post/api.py +82 -81
- udata/core/post/constants.py +8 -5
- udata/core/post/factories.py +4 -4
- udata/core/post/forms.py +13 -14
- udata/core/post/models.py +20 -22
- udata/core/post/tests/test_api.py +30 -32
- udata/core/reports/api.py +8 -7
- udata/core/reports/constants.py +1 -3
- udata/core/reports/models.py +10 -10
- udata/core/reuse/activities.py +15 -19
- udata/core/reuse/api.py +123 -126
- udata/core/reuse/api_fields.py +120 -85
- udata/core/reuse/apiv2.py +11 -10
- udata/core/reuse/constants.py +23 -23
- udata/core/reuse/csv.py +18 -18
- udata/core/reuse/factories.py +5 -9
- udata/core/reuse/forms.py +24 -21
- udata/core/reuse/models.py +55 -51
- udata/core/reuse/permissions.py +2 -2
- udata/core/reuse/search.py +49 -46
- udata/core/reuse/signals.py +1 -1
- udata/core/reuse/tasks.py +4 -5
- udata/core/site/api.py +47 -50
- udata/core/site/factories.py +2 -2
- udata/core/site/forms.py +4 -5
- udata/core/site/models.py +94 -63
- udata/core/site/rdf.py +14 -14
- udata/core/spam/api.py +16 -9
- udata/core/spam/constants.py +4 -4
- udata/core/spam/fields.py +13 -7
- udata/core/spam/models.py +27 -20
- udata/core/spam/signals.py +1 -1
- udata/core/spam/tests/test_spam.py +6 -5
- udata/core/spatial/api.py +72 -80
- udata/core/spatial/api_fields.py +73 -58
- udata/core/spatial/commands.py +67 -64
- udata/core/spatial/constants.py +3 -3
- udata/core/spatial/factories.py +37 -54
- udata/core/spatial/forms.py +27 -26
- udata/core/spatial/geoids.py +17 -17
- udata/core/spatial/models.py +43 -47
- udata/core/spatial/tasks.py +2 -1
- udata/core/spatial/tests/test_api.py +115 -130
- udata/core/spatial/tests/test_fields.py +74 -77
- udata/core/spatial/tests/test_geoid.py +22 -22
- udata/core/spatial/tests/test_models.py +5 -7
- udata/core/spatial/translations.py +16 -16
- udata/core/storages/__init__.py +16 -18
- udata/core/storages/api.py +66 -64
- udata/core/storages/tasks.py +7 -7
- udata/core/storages/utils.py +15 -15
- udata/core/storages/views.py +5 -6
- udata/core/tags/api.py +17 -14
- udata/core/tags/csv.py +4 -4
- udata/core/tags/models.py +8 -5
- udata/core/tags/tasks.py +11 -13
- udata/core/tags/views.py +4 -4
- udata/core/topic/api.py +84 -73
- udata/core/topic/apiv2.py +157 -127
- udata/core/topic/factories.py +3 -4
- udata/core/topic/forms.py +12 -14
- udata/core/topic/models.py +14 -19
- udata/core/topic/parsers.py +26 -26
- udata/core/user/activities.py +30 -29
- udata/core/user/api.py +151 -152
- udata/core/user/api_fields.py +132 -100
- udata/core/user/apiv2.py +7 -7
- udata/core/user/commands.py +38 -38
- udata/core/user/factories.py +8 -9
- udata/core/user/forms.py +14 -11
- udata/core/user/metrics.py +2 -2
- udata/core/user/models.py +68 -69
- udata/core/user/permissions.py +4 -5
- udata/core/user/rdf.py +7 -8
- udata/core/user/tasks.py +2 -2
- udata/core/user/tests/test_user_model.py +24 -16
- udata/cors.py +99 -0
- udata/db/tasks.py +2 -1
- udata/entrypoints.py +35 -31
- udata/errors.py +2 -1
- udata/event/values.py +6 -6
- udata/factories.py +2 -2
- udata/features/identicon/api.py +5 -6
- udata/features/identicon/backends.py +48 -55
- udata/features/identicon/tests/test_backends.py +4 -5
- udata/features/notifications/__init__.py +0 -1
- udata/features/notifications/actions.py +9 -9
- udata/features/notifications/api.py +17 -13
- udata/features/territories/__init__.py +12 -10
- udata/features/territories/api.py +14 -15
- udata/features/territories/models.py +23 -28
- udata/features/transfer/actions.py +8 -11
- udata/features/transfer/api.py +84 -77
- udata/features/transfer/factories.py +2 -1
- udata/features/transfer/models.py +11 -12
- udata/features/transfer/notifications.py +19 -15
- udata/features/transfer/permissions.py +5 -5
- udata/forms/__init__.py +5 -2
- udata/forms/fields.py +164 -172
- udata/forms/validators.py +19 -22
- udata/forms/widgets.py +9 -13
- udata/frontend/__init__.py +31 -26
- udata/frontend/csv.py +68 -58
- udata/frontend/markdown.py +40 -44
- udata/harvest/actions.py +89 -77
- udata/harvest/api.py +294 -238
- udata/harvest/backends/__init__.py +4 -4
- udata/harvest/backends/base.py +128 -111
- udata/harvest/backends/dcat.py +80 -66
- udata/harvest/commands.py +56 -60
- udata/harvest/csv.py +8 -8
- udata/harvest/exceptions.py +6 -3
- udata/harvest/filters.py +24 -23
- udata/harvest/forms.py +27 -28
- udata/harvest/models.py +88 -80
- udata/harvest/notifications.py +15 -10
- udata/harvest/signals.py +13 -13
- udata/harvest/tasks.py +11 -10
- udata/harvest/tests/factories.py +23 -24
- udata/harvest/tests/test_actions.py +136 -166
- udata/harvest/tests/test_api.py +220 -214
- udata/harvest/tests/test_base_backend.py +117 -112
- udata/harvest/tests/test_dcat_backend.py +380 -308
- udata/harvest/tests/test_filters.py +33 -22
- udata/harvest/tests/test_models.py +11 -14
- udata/harvest/tests/test_notifications.py +6 -7
- udata/harvest/tests/test_tasks.py +7 -6
- udata/i18n.py +237 -78
- udata/linkchecker/backends.py +5 -11
- udata/linkchecker/checker.py +23 -22
- udata/linkchecker/commands.py +4 -6
- udata/linkchecker/models.py +6 -6
- udata/linkchecker/tasks.py +18 -20
- udata/mail.py +21 -21
- udata/migrations/2020-07-24-remove-s-from-scope-oauth.py +9 -8
- udata/migrations/2020-08-24-add-fs-filename.py +9 -8
- udata/migrations/2020-09-28-update-reuses-datasets-metrics.py +5 -4
- udata/migrations/2020-10-16-migrate-ods-resources.py +9 -10
- udata/migrations/2021-04-08-update-schema-with-new-structure.py +8 -7
- udata/migrations/2021-05-27-fix-default-schema-name.py +7 -6
- udata/migrations/2021-07-05-remove-unused-badges.py +17 -15
- udata/migrations/2021-07-07-update-schema-for-community-resources.py +7 -6
- udata/migrations/2021-08-17-follow-integrity.py +5 -4
- udata/migrations/2021-08-17-harvest-integrity.py +13 -12
- udata/migrations/2021-08-17-oauth2client-integrity.py +5 -4
- udata/migrations/2021-08-17-transfer-integrity.py +5 -4
- udata/migrations/2021-08-17-users-integrity.py +9 -8
- udata/migrations/2021-12-14-reuse-topics.py +7 -6
- udata/migrations/2022-04-21-improve-extension-detection.py +8 -7
- udata/migrations/2022-09-22-clean-inactive-harvest-datasets.py +16 -14
- udata/migrations/2022-10-10-add-fs_uniquifier-to-user-model.py +6 -6
- udata/migrations/2022-10-10-migrate-harvest-extras.py +36 -26
- udata/migrations/2023-02-08-rename-internal-dates.py +46 -28
- udata/migrations/2024-01-29-fix-reuse-and-dataset-with-private-None.py +10 -8
- udata/migrations/2024-03-22-migrate-activity-kwargs-to-extras.py +6 -4
- udata/migrations/2024-06-11-fix-reuse-datasets-references.py +7 -6
- udata/migrations/__init__.py +123 -105
- udata/models/__init__.py +4 -4
- udata/mongo/__init__.py +13 -11
- udata/mongo/badges_field.py +3 -2
- udata/mongo/datetime_fields.py +13 -12
- udata/mongo/document.py +17 -16
- udata/mongo/engine.py +15 -16
- udata/mongo/errors.py +2 -1
- udata/mongo/extras_fields.py +30 -20
- udata/mongo/queryset.py +12 -12
- udata/mongo/slug_fields.py +38 -28
- udata/mongo/taglist_field.py +1 -2
- udata/mongo/url_field.py +5 -5
- udata/mongo/uuid_fields.py +4 -3
- udata/notifications/__init__.py +1 -1
- udata/notifications/mattermost.py +10 -9
- udata/rdf.py +167 -188
- udata/routing.py +40 -45
- udata/search/__init__.py +18 -19
- udata/search/adapter.py +17 -16
- udata/search/commands.py +44 -51
- udata/search/fields.py +13 -20
- udata/search/query.py +23 -18
- udata/search/result.py +9 -10
- udata/sentry.py +21 -19
- udata/settings.py +262 -198
- udata/sitemap.py +8 -6
- udata/storage/s3.py +20 -13
- udata/tags.py +4 -5
- udata/tasks.py +43 -42
- udata/tests/__init__.py +9 -6
- udata/tests/api/__init__.py +8 -6
- udata/tests/api/test_auth_api.py +395 -321
- udata/tests/api/test_base_api.py +33 -35
- udata/tests/api/test_contact_points.py +7 -9
- udata/tests/api/test_dataservices_api.py +211 -158
- udata/tests/api/test_datasets_api.py +823 -812
- udata/tests/api/test_follow_api.py +13 -15
- udata/tests/api/test_me_api.py +95 -112
- udata/tests/api/test_organizations_api.py +301 -339
- udata/tests/api/test_reports_api.py +35 -25
- udata/tests/api/test_reuses_api.py +134 -139
- udata/tests/api/test_swagger.py +5 -5
- udata/tests/api/test_tags_api.py +18 -25
- udata/tests/api/test_topics_api.py +94 -94
- udata/tests/api/test_transfer_api.py +53 -48
- udata/tests/api/test_user_api.py +128 -141
- udata/tests/apiv2/test_datasets.py +290 -198
- udata/tests/apiv2/test_me_api.py +10 -11
- udata/tests/apiv2/test_organizations.py +56 -74
- udata/tests/apiv2/test_swagger.py +5 -5
- udata/tests/apiv2/test_topics.py +69 -87
- udata/tests/cli/test_cli_base.py +8 -8
- udata/tests/cli/test_db_cli.py +21 -19
- udata/tests/dataservice/test_dataservice_tasks.py +8 -12
- udata/tests/dataset/test_csv_adapter.py +44 -35
- udata/tests/dataset/test_dataset_actions.py +2 -3
- udata/tests/dataset/test_dataset_commands.py +7 -8
- udata/tests/dataset/test_dataset_events.py +36 -29
- udata/tests/dataset/test_dataset_model.py +224 -217
- udata/tests/dataset/test_dataset_rdf.py +142 -131
- udata/tests/dataset/test_dataset_tasks.py +15 -15
- udata/tests/dataset/test_resource_preview.py +10 -13
- udata/tests/features/territories/__init__.py +9 -13
- udata/tests/features/territories/test_territories_api.py +71 -91
- udata/tests/forms/test_basic_fields.py +7 -7
- udata/tests/forms/test_current_user_field.py +39 -66
- udata/tests/forms/test_daterange_field.py +31 -39
- udata/tests/forms/test_dict_field.py +28 -26
- udata/tests/forms/test_extras_fields.py +102 -76
- udata/tests/forms/test_form_field.py +8 -8
- udata/tests/forms/test_image_field.py +33 -26
- udata/tests/forms/test_model_field.py +134 -123
- udata/tests/forms/test_model_list_field.py +7 -7
- udata/tests/forms/test_nested_model_list_field.py +117 -79
- udata/tests/forms/test_publish_as_field.py +36 -65
- udata/tests/forms/test_reference_field.py +34 -53
- udata/tests/forms/test_user_forms.py +23 -21
- udata/tests/forms/test_uuid_field.py +6 -10
- udata/tests/frontend/__init__.py +9 -6
- udata/tests/frontend/test_auth.py +7 -6
- udata/tests/frontend/test_csv.py +81 -96
- udata/tests/frontend/test_hooks.py +43 -43
- udata/tests/frontend/test_markdown.py +211 -191
- udata/tests/helpers.py +32 -37
- udata/tests/models.py +2 -2
- udata/tests/organization/test_csv_adapter.py +21 -16
- udata/tests/organization/test_notifications.py +11 -18
- udata/tests/organization/test_organization_model.py +13 -13
- udata/tests/organization/test_organization_rdf.py +29 -22
- udata/tests/organization/test_organization_tasks.py +16 -17
- udata/tests/plugin.py +79 -73
- udata/tests/reuse/test_reuse_model.py +21 -21
- udata/tests/reuse/test_reuse_task.py +11 -13
- udata/tests/search/__init__.py +11 -12
- udata/tests/search/test_adapter.py +60 -70
- udata/tests/search/test_query.py +16 -16
- udata/tests/search/test_results.py +10 -7
- udata/tests/site/test_site_api.py +11 -16
- udata/tests/site/test_site_metrics.py +20 -30
- udata/tests/site/test_site_model.py +4 -5
- udata/tests/site/test_site_rdf.py +94 -78
- udata/tests/test_activity.py +17 -17
- udata/tests/test_cors.py +62 -0
- udata/tests/test_discussions.py +292 -299
- udata/tests/test_i18n.py +37 -40
- udata/tests/test_linkchecker.py +91 -85
- udata/tests/test_mail.py +13 -17
- udata/tests/test_migrations.py +219 -180
- udata/tests/test_model.py +164 -157
- udata/tests/test_notifications.py +17 -17
- udata/tests/test_owned.py +14 -14
- udata/tests/test_rdf.py +25 -23
- udata/tests/test_routing.py +89 -93
- udata/tests/test_storages.py +137 -128
- udata/tests/test_tags.py +44 -46
- udata/tests/test_topics.py +7 -7
- udata/tests/test_transfer.py +42 -49
- udata/tests/test_uris.py +160 -161
- udata/tests/test_utils.py +79 -71
- udata/tests/user/test_user_rdf.py +5 -9
- udata/tests/workers/test_jobs_commands.py +57 -58
- udata/tests/workers/test_tasks_routing.py +23 -29
- udata/tests/workers/test_workers_api.py +125 -131
- udata/tests/workers/test_workers_helpers.py +6 -6
- udata/tracking.py +4 -6
- udata/uris.py +45 -46
- udata/utils.py +68 -66
- udata/wsgi.py +1 -1
- {udata-9.1.2.dev30355.dist-info → udata-9.1.2.dev30454.dist-info}/METADATA +7 -3
- udata-9.1.2.dev30454.dist-info/RECORD +706 -0
- udata-9.1.2.dev30355.dist-info/RECORD +0 -704
- {udata-9.1.2.dev30355.dist-info → udata-9.1.2.dev30454.dist-info}/LICENSE +0 -0
- {udata-9.1.2.dev30355.dist-info → udata-9.1.2.dev30454.dist-info}/WHEEL +0 -0
- {udata-9.1.2.dev30355.dist-info → udata-9.1.2.dev30454.dist-info}/entry_points.txt +0 -0
- {udata-9.1.2.dev30355.dist-info → udata-9.1.2.dev30454.dist-info}/top_level.txt +0 -0
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import pytest
|
|
2
|
-
|
|
3
2
|
from flask import url_for
|
|
4
|
-
|
|
5
|
-
from rdflib import
|
|
6
|
-
from rdflib.namespace import RDF, FOAF
|
|
3
|
+
from rdflib import Graph, Literal, URIRef
|
|
4
|
+
from rdflib.namespace import FOAF, RDF
|
|
7
5
|
from rdflib.resource import Resource
|
|
8
6
|
|
|
9
7
|
from udata.core.dataservices.factories import DataserviceFactory, HarvestMetadataFactory
|
|
@@ -16,17 +14,15 @@ from udata.core.user.factories import UserFactory
|
|
|
16
14
|
from udata.rdf import CONTEXT, DCAT, DCT, HYDRA
|
|
17
15
|
from udata.tests.helpers import assert200, assert404, assert_redirects
|
|
18
16
|
|
|
19
|
-
|
|
20
|
-
pytestmark = pytest.mark.usefixtures('clean_db')
|
|
17
|
+
pytestmark = pytest.mark.usefixtures("clean_db")
|
|
21
18
|
|
|
22
19
|
|
|
23
20
|
@pytest.mark.frontend
|
|
24
21
|
class CatalogTest:
|
|
25
|
-
|
|
26
22
|
def test_minimal(self, app):
|
|
27
23
|
site = SiteFactory()
|
|
28
|
-
home_url = url_for(
|
|
29
|
-
uri = url_for(
|
|
24
|
+
home_url = url_for("api.site", _external=True)
|
|
25
|
+
uri = url_for("api.site_rdf_catalog", _external=True)
|
|
30
26
|
datasets = DatasetFactory.create_batch(3)
|
|
31
27
|
catalog = build_catalog(site, datasets)
|
|
32
28
|
graph = catalog.graph
|
|
@@ -41,7 +37,7 @@ class CatalogTest:
|
|
|
41
37
|
assert str(catalog.identifier) == uri
|
|
42
38
|
assert catalog.value(DCT.title) == Literal(site.title)
|
|
43
39
|
assert catalog.value(DCT.description) == Literal(f"{site.title}")
|
|
44
|
-
lang = app.config[
|
|
40
|
+
lang = app.config["DEFAULT_LANGUAGE"]
|
|
45
41
|
assert catalog.value(DCT.language) == Literal(lang)
|
|
46
42
|
|
|
47
43
|
assert len(list(catalog.objects(DCAT.dataset))) == len(datasets)
|
|
@@ -50,7 +46,7 @@ class CatalogTest:
|
|
|
50
46
|
|
|
51
47
|
org = catalog.value(DCT.publisher)
|
|
52
48
|
assert org.value(RDF.type).identifier == FOAF.Organization
|
|
53
|
-
assert org.value(FOAF.name) == Literal(app.config[
|
|
49
|
+
assert org.value(FOAF.name) == Literal(app.config["SITE_AUTHOR"])
|
|
54
50
|
|
|
55
51
|
graph = catalog.graph
|
|
56
52
|
graph_datasets = graph.subjects(RDF.type, DCAT.Dataset)
|
|
@@ -78,16 +74,26 @@ class CatalogTest:
|
|
|
78
74
|
site = SiteFactory()
|
|
79
75
|
page_size = 3
|
|
80
76
|
total = 4
|
|
81
|
-
uri = url_for(
|
|
82
|
-
uri_first = url_for(
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
77
|
+
uri = url_for("api.site_rdf_catalog", _external=True)
|
|
78
|
+
uri_first = url_for(
|
|
79
|
+
"api.site_rdf_catalog_format",
|
|
80
|
+
format="json",
|
|
81
|
+
page=1,
|
|
82
|
+
page_size=page_size,
|
|
83
|
+
_external=True,
|
|
84
|
+
)
|
|
85
|
+
uri_last = url_for(
|
|
86
|
+
"api.site_rdf_catalog_format",
|
|
87
|
+
format="json",
|
|
88
|
+
page=2,
|
|
89
|
+
page_size=page_size,
|
|
90
|
+
_external=True,
|
|
91
|
+
)
|
|
86
92
|
DatasetFactory.create_batch(total)
|
|
87
93
|
|
|
88
94
|
# First page
|
|
89
95
|
datasets = Dataset.objects.paginate(1, page_size)
|
|
90
|
-
catalog = build_catalog(site, datasets, format=
|
|
96
|
+
catalog = build_catalog(site, datasets, format="json")
|
|
91
97
|
graph = catalog.graph
|
|
92
98
|
|
|
93
99
|
assert isinstance(catalog, Resource)
|
|
@@ -100,8 +106,7 @@ class CatalogTest:
|
|
|
100
106
|
|
|
101
107
|
assert len(list(catalog.objects(DCAT.dataset))) == page_size
|
|
102
108
|
|
|
103
|
-
paginations = list(graph.subjects(RDF.type,
|
|
104
|
-
HYDRA.PartialCollectionView))
|
|
109
|
+
paginations = list(graph.subjects(RDF.type, HYDRA.PartialCollectionView))
|
|
105
110
|
assert len(paginations) == 1
|
|
106
111
|
pagination = graph.resource(paginations[0])
|
|
107
112
|
assert pagination.identifier == URIRef(uri_first)
|
|
@@ -112,7 +117,7 @@ class CatalogTest:
|
|
|
112
117
|
|
|
113
118
|
# Second page
|
|
114
119
|
datasets = Dataset.objects.paginate(2, page_size)
|
|
115
|
-
catalog = build_catalog(site, datasets, format=
|
|
120
|
+
catalog = build_catalog(site, datasets, format="json")
|
|
116
121
|
graph = catalog.graph
|
|
117
122
|
|
|
118
123
|
assert isinstance(catalog, Resource)
|
|
@@ -125,8 +130,7 @@ class CatalogTest:
|
|
|
125
130
|
|
|
126
131
|
assert len(list(catalog.objects(DCAT.dataset))) == 1
|
|
127
132
|
|
|
128
|
-
paginations = list(graph.subjects(RDF.type,
|
|
129
|
-
HYDRA.PartialCollectionView))
|
|
133
|
+
paginations = list(graph.subjects(RDF.type, HYDRA.PartialCollectionView))
|
|
130
134
|
assert len(paginations) == 1
|
|
131
135
|
pagination = graph.resource(paginations[0])
|
|
132
136
|
assert pagination.identifier == URIRef(uri_last)
|
|
@@ -138,128 +142,132 @@ class CatalogTest:
|
|
|
138
142
|
|
|
139
143
|
@pytest.mark.frontend
|
|
140
144
|
class SiteRdfViewsTest:
|
|
141
|
-
|
|
142
145
|
def test_expose_jsonld_context(self, client):
|
|
143
|
-
url = url_for(
|
|
144
|
-
assert url ==
|
|
146
|
+
url = url_for("api.site_jsonld_context")
|
|
147
|
+
assert url == "/api/1/site/context.jsonld"
|
|
145
148
|
|
|
146
|
-
response = client.get(url, headers={
|
|
149
|
+
response = client.get(url, headers={"Accept": "application/ld+json"})
|
|
147
150
|
assert200(response)
|
|
148
|
-
assert response.content_type ==
|
|
151
|
+
assert response.content_type == "application/ld+json"
|
|
149
152
|
assert response.json == CONTEXT
|
|
150
153
|
|
|
151
154
|
def test_catalog_default_to_jsonld(self, client):
|
|
152
|
-
expected = url_for(
|
|
153
|
-
response = client.get(url_for(
|
|
155
|
+
expected = url_for("api.site_rdf_catalog_format", format="json")
|
|
156
|
+
response = client.get(url_for("api.site_rdf_catalog"))
|
|
154
157
|
assert_redirects(response, expected)
|
|
155
158
|
|
|
156
159
|
def test_rdf_perform_content_negociation(self, client):
|
|
157
|
-
expected = url_for(
|
|
158
|
-
url = url_for(
|
|
159
|
-
headers = {
|
|
160
|
+
expected = url_for("api.site_rdf_catalog_format", format="xml")
|
|
161
|
+
url = url_for("api.site_rdf_catalog")
|
|
162
|
+
headers = {"accept": "application/xml"}
|
|
160
163
|
response = client.get(url, headers=headers)
|
|
161
164
|
assert_redirects(response, expected)
|
|
162
165
|
|
|
163
|
-
@pytest.mark.parametrize(
|
|
166
|
+
@pytest.mark.parametrize("fmt", ("json", "jsonld"))
|
|
164
167
|
def test_catalog_rdf_json_ld(self, fmt, client):
|
|
165
|
-
url = url_for(
|
|
166
|
-
response = client.get(url, headers={
|
|
168
|
+
url = url_for("api.site_rdf_catalog_format", format=fmt)
|
|
169
|
+
response = client.get(url, headers={"Accept": "application/ld+json"})
|
|
167
170
|
assert200(response)
|
|
168
|
-
assert response.content_type ==
|
|
169
|
-
assert response.json[
|
|
171
|
+
assert response.content_type == "application/ld+json"
|
|
172
|
+
assert response.json["@context"]["@vocab"] == "http://www.w3.org/ns/dcat#"
|
|
170
173
|
|
|
171
174
|
def test_catalog_rdf_n3(self, client):
|
|
172
|
-
url = url_for(
|
|
173
|
-
response = client.get(url, headers={
|
|
175
|
+
url = url_for("api.site_rdf_catalog_format", format="n3")
|
|
176
|
+
response = client.get(url, headers={"Accept": "text/n3"})
|
|
174
177
|
assert200(response)
|
|
175
|
-
assert response.content_type ==
|
|
178
|
+
assert response.content_type == "text/n3"
|
|
176
179
|
|
|
177
180
|
def test_catalog_rdf_turtle(self, client):
|
|
178
|
-
url = url_for(
|
|
179
|
-
response = client.get(url, headers={
|
|
181
|
+
url = url_for("api.site_rdf_catalog_format", format="ttl")
|
|
182
|
+
response = client.get(url, headers={"Accept": "application/x-turtle"})
|
|
180
183
|
assert200(response)
|
|
181
|
-
assert response.content_type ==
|
|
184
|
+
assert response.content_type == "application/x-turtle"
|
|
182
185
|
|
|
183
|
-
@pytest.mark.parametrize(
|
|
186
|
+
@pytest.mark.parametrize("fmt", ("xml", "rdf", "owl"))
|
|
184
187
|
def test_catalog_rdf_rdfxml(self, fmt, client):
|
|
185
|
-
url = url_for(
|
|
186
|
-
response = client.get(url, headers={
|
|
188
|
+
url = url_for("api.site_rdf_catalog_format", format=fmt)
|
|
189
|
+
response = client.get(url, headers={"Accept": "application/rdf+xml"})
|
|
187
190
|
assert200(response)
|
|
188
|
-
assert response.content_type ==
|
|
191
|
+
assert response.content_type == "application/rdf+xml"
|
|
189
192
|
|
|
190
193
|
def test_catalog_rdf_n_triples(self, client):
|
|
191
|
-
url = url_for(
|
|
192
|
-
response = client.get(url, headers={
|
|
194
|
+
url = url_for("api.site_rdf_catalog_format", format="nt")
|
|
195
|
+
response = client.get(url, headers={"Accept": "application/n-triples"})
|
|
193
196
|
assert200(response)
|
|
194
|
-
assert response.content_type ==
|
|
197
|
+
assert response.content_type == "application/n-triples"
|
|
195
198
|
|
|
196
199
|
def test_catalog_rdf_trig(self, client):
|
|
197
|
-
url = url_for(
|
|
198
|
-
response = client.get(url, headers={
|
|
200
|
+
url = url_for("api.site_rdf_catalog_format", format="trig")
|
|
201
|
+
response = client.get(url, headers={"Accept": "application/trig"})
|
|
199
202
|
assert200(response)
|
|
200
|
-
assert response.content_type ==
|
|
203
|
+
assert response.content_type == "application/trig"
|
|
201
204
|
|
|
202
|
-
@pytest.mark.parametrize(
|
|
205
|
+
@pytest.mark.parametrize("fmt", ("json", "xml", "ttl"))
|
|
203
206
|
def test_dataportal_compliance(self, fmt, client):
|
|
204
|
-
url = url_for(
|
|
205
|
-
assert url ==
|
|
206
|
-
expected_url = url_for(
|
|
207
|
+
url = url_for("api.site_dataportal", format=fmt)
|
|
208
|
+
assert url == "/api/1/site/data.{0}".format(fmt)
|
|
209
|
+
expected_url = url_for("api.site_rdf_catalog_format", format=fmt)
|
|
207
210
|
|
|
208
211
|
response = client.get(url)
|
|
209
212
|
assert_redirects(response, expected_url)
|
|
210
213
|
|
|
211
214
|
def test_catalog_rdf_paginate(self, client):
|
|
212
215
|
DatasetFactory.create_batch(4)
|
|
213
|
-
url = url_for(
|
|
214
|
-
next_url = url_for(
|
|
215
|
-
|
|
216
|
+
url = url_for("api.site_rdf_catalog_format", format="n3", page_size=3)
|
|
217
|
+
next_url = url_for(
|
|
218
|
+
"api.site_rdf_catalog_format", format="n3", page=2, page_size=3, _external=True
|
|
219
|
+
)
|
|
216
220
|
|
|
217
|
-
response = client.get(url, headers={
|
|
221
|
+
response = client.get(url, headers={"Accept": "text/n3"})
|
|
218
222
|
assert200(response)
|
|
219
223
|
|
|
220
|
-
graph = Graph().parse(data=response.data, format=
|
|
221
|
-
pagination = graph.value(predicate=RDF.type,
|
|
222
|
-
object=HYDRA.PartialCollectionView)
|
|
224
|
+
graph = Graph().parse(data=response.data, format="n3")
|
|
225
|
+
pagination = graph.value(predicate=RDF.type, object=HYDRA.PartialCollectionView)
|
|
223
226
|
assert pagination is not None
|
|
224
227
|
pagination = graph.resource(pagination)
|
|
225
228
|
assert not pagination.value(HYDRA.previous)
|
|
226
229
|
assert pagination.value(HYDRA.next).identifier == URIRef(next_url)
|
|
227
230
|
|
|
228
231
|
def test_catalog_format_unknown(self, client):
|
|
229
|
-
url = url_for(
|
|
232
|
+
url = url_for("api.site_rdf_catalog_format", format="unknown")
|
|
230
233
|
response = client.get(url)
|
|
231
234
|
assert404(response)
|
|
232
235
|
|
|
233
236
|
def test_catalog_rdf_filter_tag(self, client):
|
|
234
|
-
DatasetFactory.create_batch(4, tags=[
|
|
237
|
+
DatasetFactory.create_batch(4, tags=["my-tag"])
|
|
235
238
|
DatasetFactory.create_batch(3)
|
|
236
|
-
url = url_for(
|
|
239
|
+
url = url_for("api.site_rdf_catalog_format", format="xml", tag="my-tag")
|
|
237
240
|
|
|
238
|
-
response = client.get(url, headers={
|
|
241
|
+
response = client.get(url, headers={"Accept": "application/xml"})
|
|
239
242
|
assert200(response)
|
|
240
243
|
|
|
241
|
-
graph = Graph().parse(data=response.data, format=
|
|
244
|
+
graph = Graph().parse(data=response.data, format="xml")
|
|
242
245
|
|
|
243
246
|
datasets = list(graph.subjects(RDF.type, DCAT.Dataset))
|
|
244
247
|
assert len(datasets) == 4
|
|
245
248
|
|
|
246
249
|
for dat in datasets:
|
|
247
|
-
assert graph.value(dat, DCAT.keyword) == Literal(
|
|
250
|
+
assert graph.value(dat, DCAT.keyword) == Literal("my-tag")
|
|
248
251
|
|
|
249
252
|
def test_catalog_rdf_dataservices(self, client):
|
|
250
253
|
dataset_a = DatasetFactory.create()
|
|
251
254
|
dataset_b = DatasetFactory.create()
|
|
252
255
|
dataset_c = DatasetFactory.create()
|
|
253
256
|
|
|
254
|
-
dataservice_a = DataserviceFactory.create(
|
|
257
|
+
dataservice_a = DataserviceFactory.create(
|
|
258
|
+
datasets=[dataset_a.id], harvest=HarvestMetadataFactory()
|
|
259
|
+
)
|
|
255
260
|
dataservice_b = DataserviceFactory.create(datasets=[dataset_b.id])
|
|
256
261
|
dataservice_x = DataserviceFactory.create(datasets=[dataset_a.id, dataset_c.id])
|
|
257
262
|
dataservice_y = DataserviceFactory.create(datasets=[])
|
|
258
263
|
|
|
259
|
-
response = client.get(
|
|
264
|
+
response = client.get(
|
|
265
|
+
url_for("api.site_rdf_catalog_format", format="xml"),
|
|
266
|
+
headers={"Accept": "application/xml"},
|
|
267
|
+
)
|
|
260
268
|
assert200(response)
|
|
261
269
|
|
|
262
|
-
graph = Graph().parse(data=response.data, format=
|
|
270
|
+
graph = Graph().parse(data=response.data, format="xml")
|
|
263
271
|
|
|
264
272
|
datasets = list(graph.subjects(RDF.type, DCAT.Dataset))
|
|
265
273
|
assert len(datasets) == 3
|
|
@@ -268,10 +276,13 @@ class SiteRdfViewsTest:
|
|
|
268
276
|
assert len(dataservices) == 4
|
|
269
277
|
|
|
270
278
|
# Test first page contains the dataservice without dataset
|
|
271
|
-
response = client.get(
|
|
279
|
+
response = client.get(
|
|
280
|
+
url_for("api.site_rdf_catalog_format", format="xml", page_size=1),
|
|
281
|
+
headers={"Accept": "application/xml"},
|
|
282
|
+
)
|
|
272
283
|
assert200(response)
|
|
273
284
|
|
|
274
|
-
graph = Graph().parse(data=response.data, format=
|
|
285
|
+
graph = Graph().parse(data=response.data, format="xml")
|
|
275
286
|
|
|
276
287
|
datasets = list(graph.subjects(RDF.type, DCAT.Dataset))
|
|
277
288
|
assert len(datasets) == 1
|
|
@@ -279,13 +290,18 @@ class SiteRdfViewsTest:
|
|
|
279
290
|
|
|
280
291
|
dataservices = list(graph.subjects(RDF.type, DCAT.DataService))
|
|
281
292
|
assert len(dataservices) == 2
|
|
282
|
-
assert sorted([str(d.id) for d in [dataservice_x, dataservice_y]]) == sorted(
|
|
293
|
+
assert sorted([str(d.id) for d in [dataservice_x, dataservice_y]]) == sorted(
|
|
294
|
+
[str(graph.value(d, DCT.identifier)) for d in dataservices]
|
|
295
|
+
)
|
|
283
296
|
|
|
284
297
|
# Test second page doesn't contains the dataservice without dataset
|
|
285
|
-
response = client.get(
|
|
298
|
+
response = client.get(
|
|
299
|
+
url_for("api.site_rdf_catalog_format", format="xml", page_size=1, page=2),
|
|
300
|
+
headers={"Accept": "application/xml"},
|
|
301
|
+
)
|
|
286
302
|
assert200(response)
|
|
287
303
|
|
|
288
|
-
graph = Graph().parse(data=response.data, format=
|
|
304
|
+
graph = Graph().parse(data=response.data, format="xml")
|
|
289
305
|
|
|
290
306
|
datasets = list(graph.subjects(RDF.type, DCAT.Dataset))
|
|
291
307
|
assert len(datasets) == 1
|
udata/tests/test_activity.py
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
from udata.models import db, Activity
|
|
2
|
-
from udata.tests import TestCase, DBTestMixin, WebTestMixin
|
|
3
|
-
from udata.core.user.factories import UserFactory
|
|
4
|
-
from udata.core.organization.factories import OrganizationFactory
|
|
5
1
|
from udata.auth import login_user
|
|
2
|
+
from udata.core.organization.factories import OrganizationFactory
|
|
3
|
+
from udata.core.user.factories import UserFactory
|
|
4
|
+
from udata.models import Activity, db
|
|
5
|
+
from udata.tests import DBTestMixin, TestCase, WebTestMixin
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
class FakeSubject(db.Document):
|
|
@@ -10,13 +10,13 @@ class FakeSubject(db.Document):
|
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
class FakeActivity(Activity):
|
|
13
|
-
key =
|
|
13
|
+
key = "fake"
|
|
14
14
|
related_to = db.ReferenceField(FakeSubject)
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
class ActivityTest(WebTestMixin, DBTestMixin, TestCase):
|
|
18
18
|
def setUp(self):
|
|
19
|
-
self.fake = FakeSubject.objects.create(name=
|
|
19
|
+
self.fake = FakeSubject.objects.create(name="fake")
|
|
20
20
|
self.login()
|
|
21
21
|
|
|
22
22
|
def test_create_and_retrieve_for_user(self):
|
|
@@ -28,21 +28,22 @@ class ActivityTest(WebTestMixin, DBTestMixin, TestCase):
|
|
|
28
28
|
self.assertIsInstance(activities[0], FakeActivity)
|
|
29
29
|
|
|
30
30
|
def test_create_and_retrieve_with_extras(self):
|
|
31
|
-
FakeActivity.objects.create(
|
|
32
|
-
|
|
31
|
+
FakeActivity.objects.create(
|
|
32
|
+
actor=self.user,
|
|
33
|
+
related_to=self.fake,
|
|
34
|
+
extras={"some_key": "some_value", "other_key": "other_value"},
|
|
35
|
+
)
|
|
33
36
|
|
|
34
37
|
activities = Activity.objects(actor=self.user)
|
|
35
38
|
|
|
36
39
|
self.assertEqual(len(activities), 1)
|
|
37
|
-
self.assertEqual(activities[0].extras[
|
|
38
|
-
self.assertEqual(activities[0].extras[
|
|
40
|
+
self.assertEqual(activities[0].extras["some_key"], "some_value")
|
|
41
|
+
self.assertEqual(activities[0].extras["other_key"], "other_value")
|
|
39
42
|
self.assertIsInstance(activities[0], FakeActivity)
|
|
40
43
|
|
|
41
|
-
|
|
42
44
|
def test_create_and_retrieve_for_org(self):
|
|
43
45
|
org = OrganizationFactory()
|
|
44
|
-
FakeActivity.objects.create(
|
|
45
|
-
actor=self.user, related_to=self.fake, organization=org)
|
|
46
|
+
FakeActivity.objects.create(actor=self.user, related_to=self.fake, organization=org)
|
|
46
47
|
|
|
47
48
|
activities = Activity.objects(organization=org)
|
|
48
49
|
|
|
@@ -51,8 +52,7 @@ class ActivityTest(WebTestMixin, DBTestMixin, TestCase):
|
|
|
51
52
|
|
|
52
53
|
def test_create_and_retrieve_for_related(self):
|
|
53
54
|
org = OrganizationFactory()
|
|
54
|
-
FakeActivity.objects.create(
|
|
55
|
-
actor=self.user, related_to=self.fake, organization=org)
|
|
55
|
+
FakeActivity.objects.create(actor=self.user, related_to=self.fake, organization=org)
|
|
56
56
|
FakeActivity.objects.create(actor=UserFactory(), related_to=self.fake)
|
|
57
57
|
|
|
58
58
|
activities = Activity.objects(related_to=self.fake)
|
|
@@ -67,7 +67,7 @@ class ActivityTest(WebTestMixin, DBTestMixin, TestCase):
|
|
|
67
67
|
self.emitted = True
|
|
68
68
|
|
|
69
69
|
def test_emit_signal(self):
|
|
70
|
-
|
|
70
|
+
"""It should emit a signal on new activity"""
|
|
71
71
|
self.emitted = False
|
|
72
72
|
with FakeActivity.on_new.connected_to(self.check_emitted):
|
|
73
73
|
FakeActivity.objects.create(actor=self.user, related_to=self.fake)
|
|
@@ -75,7 +75,7 @@ class ActivityTest(WebTestMixin, DBTestMixin, TestCase):
|
|
|
75
75
|
self.assertTrue(self.emitted)
|
|
76
76
|
|
|
77
77
|
def test_class_shortcut(self):
|
|
78
|
-
|
|
78
|
+
"""It should emit a signal on new activity"""
|
|
79
79
|
self.emitted = False
|
|
80
80
|
self.login()
|
|
81
81
|
with self.app.app_context():
|
udata/tests/test_cors.py
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
from datetime import datetime
|
|
2
|
+
|
|
3
|
+
import pytest
|
|
4
|
+
from flask import url_for
|
|
5
|
+
|
|
6
|
+
from udata.core.dataset.factories import DatasetFactory
|
|
7
|
+
from udata.core.topic.factories import TopicFactory
|
|
8
|
+
from udata.search import reindex
|
|
9
|
+
from udata.tests.api import APITestCase
|
|
10
|
+
from udata.tests.helpers import assert_status
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class CorsTest(APITestCase):
|
|
14
|
+
modules = []
|
|
15
|
+
|
|
16
|
+
def test_cors_redirects(self):
|
|
17
|
+
dataset = DatasetFactory(title="Old title")
|
|
18
|
+
old_slug = dataset.slug
|
|
19
|
+
|
|
20
|
+
# New slug to force a redirect from old slug
|
|
21
|
+
dataset.title = "New title"
|
|
22
|
+
dataset.save()
|
|
23
|
+
|
|
24
|
+
response = self.get(url_for("api.dataset", dataset=old_slug))
|
|
25
|
+
assert_status(response, 308)
|
|
26
|
+
|
|
27
|
+
response = self.options(
|
|
28
|
+
url_for("api.dataset", dataset=old_slug),
|
|
29
|
+
headers={
|
|
30
|
+
"Origin": "http://localhost",
|
|
31
|
+
"Access-Control-Request-Method": "GET",
|
|
32
|
+
},
|
|
33
|
+
)
|
|
34
|
+
assert_status(response, 204)
|
|
35
|
+
|
|
36
|
+
def test_cors_404(self):
|
|
37
|
+
response = self.get(url_for("api.dataset", dataset="unknown-dataset"))
|
|
38
|
+
assert_status(response, 404)
|
|
39
|
+
|
|
40
|
+
response = self.options(
|
|
41
|
+
url_for("api.dataset", dataset="unknown-dataset"),
|
|
42
|
+
headers={
|
|
43
|
+
"Origin": "http://localhost",
|
|
44
|
+
"Access-Control-Request-Method": "GET",
|
|
45
|
+
},
|
|
46
|
+
)
|
|
47
|
+
assert_status(response, 204)
|
|
48
|
+
|
|
49
|
+
def test_cors_410_with_api_abort(self):
|
|
50
|
+
dataset = DatasetFactory(deleted=datetime.now())
|
|
51
|
+
|
|
52
|
+
response = self.get(url_for("api.dataset", dataset=dataset.id))
|
|
53
|
+
assert_status(response, 410)
|
|
54
|
+
|
|
55
|
+
response = self.options(
|
|
56
|
+
url_for("api.dataset", dataset=dataset.id),
|
|
57
|
+
headers={
|
|
58
|
+
"Origin": "http://localhost",
|
|
59
|
+
"Access-Control-Request-Method": "GET",
|
|
60
|
+
},
|
|
61
|
+
)
|
|
62
|
+
assert_status(response, 204)
|