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
|
@@ -20,38 +20,38 @@ class NotificationsActionsTest(NotificationsMixin, TestCase, DBTestMixin):
|
|
|
20
20
|
def fake_provider(user):
|
|
21
21
|
return []
|
|
22
22
|
|
|
23
|
-
actions.register_provider(
|
|
23
|
+
actions.register_provider("fake", fake_provider)
|
|
24
24
|
|
|
25
|
-
self.assertIn(
|
|
25
|
+
self.assertIn("fake", actions.list_providers())
|
|
26
26
|
|
|
27
27
|
def test_registered_provider_with_decorator_is_listed(self):
|
|
28
|
-
@actions.notifier(
|
|
28
|
+
@actions.notifier("fake")
|
|
29
29
|
def fake_provider(user):
|
|
30
30
|
return []
|
|
31
31
|
|
|
32
|
-
self.assertIn(
|
|
32
|
+
self.assertIn("fake", actions.list_providers())
|
|
33
33
|
|
|
34
34
|
def test_registered_provider_provide_values(self):
|
|
35
35
|
dt = datetime.utcnow()
|
|
36
36
|
|
|
37
37
|
def fake_provider(user):
|
|
38
|
-
return [(dt, {
|
|
38
|
+
return [(dt, {"some": "value"})]
|
|
39
39
|
|
|
40
|
-
actions.register_provider(
|
|
40
|
+
actions.register_provider("fake", fake_provider)
|
|
41
41
|
|
|
42
42
|
user = UserFactory()
|
|
43
43
|
notifs = actions.get_notifications(user)
|
|
44
44
|
|
|
45
45
|
self.assertEqual(len(notifs), 1)
|
|
46
|
-
self.assertEqual(notifs[0][
|
|
47
|
-
self.assertEqual(notifs[0][
|
|
48
|
-
self.assertEqualDates(notifs[0][
|
|
46
|
+
self.assertEqual(notifs[0]["type"], "fake")
|
|
47
|
+
self.assertEqual(notifs[0]["details"], {"some": "value"})
|
|
48
|
+
self.assertEqualDates(notifs[0]["created_on"], dt)
|
|
49
49
|
|
|
50
50
|
|
|
51
51
|
class NotificationsAPITest(NotificationsMixin, APITestCase):
|
|
52
52
|
def test_no_notifications(self):
|
|
53
53
|
self.login()
|
|
54
|
-
response = self.get(url_for(
|
|
54
|
+
response = self.get(url_for("api.notifications"))
|
|
55
55
|
self.assert200(response)
|
|
56
56
|
|
|
57
57
|
self.assertEqual(len(response.json), 0)
|
|
@@ -60,17 +60,17 @@ class NotificationsAPITest(NotificationsMixin, APITestCase):
|
|
|
60
60
|
self.login()
|
|
61
61
|
dt = datetime.utcnow()
|
|
62
62
|
|
|
63
|
-
@actions.notifier(
|
|
63
|
+
@actions.notifier("fake")
|
|
64
64
|
def fake_notifier(user):
|
|
65
|
-
return [(dt, {
|
|
65
|
+
return [(dt, {"some": "value"}), (dt, {"another": "value"})]
|
|
66
66
|
|
|
67
|
-
response = self.get(url_for(
|
|
67
|
+
response = self.get(url_for("api.notifications"))
|
|
68
68
|
self.assert200(response)
|
|
69
69
|
|
|
70
70
|
self.assertEqual(len(response.json), 2)
|
|
71
71
|
|
|
72
72
|
for notification in response.json:
|
|
73
|
-
self.assertEqual(notification[
|
|
74
|
-
self.assertEqual(notification[
|
|
75
|
-
self.assertEqual(response.json[0][
|
|
76
|
-
self.assertEqual(response.json[1][
|
|
73
|
+
self.assertEqual(notification["created_on"], pytz.utc.localize(dt).isoformat())
|
|
74
|
+
self.assertEqual(notification["type"], "fake")
|
|
75
|
+
self.assertEqual(response.json[0]["details"], {"some": "value"})
|
|
76
|
+
self.assertEqual(response.json[1]["details"], {"another": "value"})
|
udata/tests/test_owned.py
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
from mongoengine import post_save
|
|
2
2
|
|
|
3
|
+
import udata.core.owned as owned
|
|
3
4
|
from udata.core.organization.factories import OrganizationFactory
|
|
4
5
|
from udata.core.organization.models import Organization
|
|
5
6
|
from udata.core.user.factories import UserFactory
|
|
6
7
|
from udata.core.user.models import User
|
|
7
|
-
|
|
8
8
|
from udata.mongo import db
|
|
9
|
-
|
|
10
|
-
from udata.tests import TestCase, DBTestMixin
|
|
9
|
+
from udata.tests import DBTestMixin, TestCase
|
|
11
10
|
|
|
12
11
|
|
|
13
12
|
class Owned(owned.Owned, db.Document):
|
|
@@ -17,9 +16,9 @@ class Owned(owned.Owned, db.Document):
|
|
|
17
16
|
class OwnedPostSave(owned.Owned, db.Document):
|
|
18
17
|
@classmethod
|
|
19
18
|
def post_save(cls, sender, document, **kwargs):
|
|
20
|
-
if
|
|
19
|
+
if "post_save" in kwargs.get("ignores", []):
|
|
21
20
|
return
|
|
22
|
-
if kwargs.get(
|
|
21
|
+
if kwargs.get("created"):
|
|
23
22
|
pass
|
|
24
23
|
else:
|
|
25
24
|
# on update
|
|
@@ -28,7 +27,7 @@ class OwnedPostSave(owned.Owned, db.Document):
|
|
|
28
27
|
|
|
29
28
|
def compute_some_metrics(document, **kwargs):
|
|
30
29
|
document.metric = 0
|
|
31
|
-
document.save(signal_kwargs={
|
|
30
|
+
document.save(signal_kwargs={"ignores": ["post_save"]})
|
|
32
31
|
|
|
33
32
|
|
|
34
33
|
class TestOwnedMixin(DBTestMixin, TestCase):
|
|
@@ -55,7 +54,7 @@ class TestOwnedMixin(DBTestMixin, TestCase):
|
|
|
55
54
|
owned.owner = second_owner
|
|
56
55
|
owned.save()
|
|
57
56
|
|
|
58
|
-
self.assertTrue(getattr(handler,
|
|
57
|
+
self.assertTrue(getattr(handler, "called", False))
|
|
59
58
|
|
|
60
59
|
def test_owner_changed_from_user_to_org(self):
|
|
61
60
|
owner = UserFactory()
|
|
@@ -73,7 +72,7 @@ class TestOwnedMixin(DBTestMixin, TestCase):
|
|
|
73
72
|
owned.organization = org
|
|
74
73
|
owned.save()
|
|
75
74
|
|
|
76
|
-
self.assertTrue(getattr(handler,
|
|
75
|
+
self.assertTrue(getattr(handler, "called", False))
|
|
77
76
|
|
|
78
77
|
def test_owner_changed_from_org_to_org(self):
|
|
79
78
|
first_org = OrganizationFactory()
|
|
@@ -91,7 +90,7 @@ class TestOwnedMixin(DBTestMixin, TestCase):
|
|
|
91
90
|
owned.organization = second_org
|
|
92
91
|
owned.save()
|
|
93
92
|
|
|
94
|
-
self.assertTrue(getattr(handler,
|
|
93
|
+
self.assertTrue(getattr(handler, "called", False))
|
|
95
94
|
|
|
96
95
|
def test_owner_changed_from_org_to_user(self):
|
|
97
96
|
user = UserFactory()
|
|
@@ -109,7 +108,7 @@ class TestOwnedMixin(DBTestMixin, TestCase):
|
|
|
109
108
|
owned.owner = user
|
|
110
109
|
owned.save()
|
|
111
110
|
|
|
112
|
-
self.assertTrue(getattr(handler,
|
|
111
|
+
self.assertTrue(getattr(handler, "called", False))
|
|
113
112
|
|
|
114
113
|
def test_owner_changed_from_org_to_user_with_owned_postsave_signal(self):
|
|
115
114
|
# Test with an additionnal post save signal that will retriger save signals
|
|
@@ -153,10 +152,11 @@ class OwnedQuerysetTest(DBTestMixin, TestCase):
|
|
|
153
152
|
def test_owned_by_org_or_user(self):
|
|
154
153
|
user = UserFactory()
|
|
155
154
|
org = OrganizationFactory()
|
|
156
|
-
owneds = [Owned.objects.create(owner=user),
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
155
|
+
owneds = [Owned.objects.create(owner=user), Owned.objects.create(organization=org)]
|
|
156
|
+
excluded = [
|
|
157
|
+
Owned.objects.create(owner=UserFactory()),
|
|
158
|
+
Owned.objects.create(organization=OrganizationFactory()),
|
|
159
|
+
]
|
|
160
160
|
|
|
161
161
|
result = Owned.objects.owned_by(org, user)
|
|
162
162
|
|
udata/tests/test_rdf.py
CHANGED
|
@@ -1,53 +1,55 @@
|
|
|
1
1
|
import pytest
|
|
2
2
|
|
|
3
|
-
from udata.tests import TestCase
|
|
4
|
-
|
|
5
|
-
|
|
6
3
|
from udata.rdf import (
|
|
7
|
-
|
|
4
|
+
ACCEPTED_MIME_TYPES,
|
|
5
|
+
FORMAT_MAP,
|
|
6
|
+
guess_format,
|
|
7
|
+
negociate_content,
|
|
8
|
+
want_rdf,
|
|
8
9
|
)
|
|
10
|
+
from udata.tests import TestCase
|
|
9
11
|
|
|
10
12
|
|
|
11
13
|
class ContentNegociationTest(TestCase):
|
|
12
14
|
def test_find_format_from_accept_header(self):
|
|
13
15
|
for mime, expected in ACCEPTED_MIME_TYPES.items():
|
|
14
|
-
headers = {
|
|
16
|
+
headers = {"accept": mime}
|
|
15
17
|
with self.app.test_request_context(headers=headers):
|
|
16
18
|
self.assertEqual(negociate_content(), expected)
|
|
17
19
|
|
|
18
20
|
def test_default_format_if_no_accept_header(self):
|
|
19
21
|
with self.app.test_request_context():
|
|
20
|
-
self.assertEqual(negociate_content(default=
|
|
22
|
+
self.assertEqual(negociate_content(default="json-ld"), "json-ld")
|
|
21
23
|
|
|
22
24
|
def test_default_format_if_unkown_accept_header(self):
|
|
23
|
-
headers = {
|
|
25
|
+
headers = {"accept": "what/ever"}
|
|
24
26
|
with self.app.test_request_context(headers=headers):
|
|
25
|
-
self.assertEqual(negociate_content(default=
|
|
27
|
+
self.assertEqual(negociate_content(default="json-ld"), "json-ld")
|
|
26
28
|
|
|
27
29
|
def test_support_accept_header_multiple_form(self):
|
|
28
|
-
headers = {
|
|
30
|
+
headers = {"accept": "application/xml, application/json"}
|
|
29
31
|
with self.app.test_request_context(headers=headers):
|
|
30
|
-
self.assertEqual(negociate_content(),
|
|
32
|
+
self.assertEqual(negociate_content(), "xml")
|
|
31
33
|
|
|
32
34
|
def test_support_accept_header_multiple_form_with_ponderation(self):
|
|
33
|
-
headers = {
|
|
35
|
+
headers = {"accept": "application/xml;q=0.8, application/json;q=0.9"}
|
|
34
36
|
with self.app.test_request_context(headers=headers):
|
|
35
|
-
self.assertEqual(negociate_content(),
|
|
37
|
+
self.assertEqual(negociate_content(), "json-ld")
|
|
36
38
|
|
|
37
39
|
def test_match_known_format_in_accept_header(self):
|
|
38
|
-
headers = {
|
|
40
|
+
headers = {"accept": "what/ever, application/xml"}
|
|
39
41
|
with self.app.test_request_context(headers=headers):
|
|
40
|
-
self.assertEqual(negociate_content(),
|
|
42
|
+
self.assertEqual(negociate_content(), "xml")
|
|
41
43
|
|
|
42
44
|
def test_want_rdf(self):
|
|
43
|
-
for mimetype in
|
|
44
|
-
headers = {
|
|
45
|
+
for mimetype in "application/xml", "application/json":
|
|
46
|
+
headers = {"accept": mimetype}
|
|
45
47
|
with self.app.test_request_context(headers=headers):
|
|
46
48
|
self.assertTrue(want_rdf())
|
|
47
49
|
|
|
48
50
|
def test_want_html(self):
|
|
49
|
-
for mimetype in
|
|
50
|
-
headers = {
|
|
51
|
+
for mimetype in "text/html", "application/xhtml+xml":
|
|
52
|
+
headers = {"accept": mimetype}
|
|
51
53
|
with self.app.test_request_context(headers=headers):
|
|
52
54
|
self.assertFalse(want_rdf())
|
|
53
55
|
|
|
@@ -56,16 +58,16 @@ class ContentNegociationTest(TestCase):
|
|
|
56
58
|
|
|
57
59
|
|
|
58
60
|
class GuessFormatTest(object):
|
|
59
|
-
@pytest.mark.parametrize(
|
|
61
|
+
@pytest.mark.parametrize("suffix,expected", FORMAT_MAP.items())
|
|
60
62
|
def test_guess_from_extension(self, suffix, expected):
|
|
61
|
-
assert guess_format(
|
|
63
|
+
assert guess_format("resource.{0}".format(suffix)) == expected
|
|
62
64
|
|
|
63
|
-
@pytest.mark.parametrize(
|
|
65
|
+
@pytest.mark.parametrize("mime,expected", ACCEPTED_MIME_TYPES.items())
|
|
64
66
|
def test_guess_from_mime_type(self, mime, expected):
|
|
65
67
|
assert guess_format(mime) == expected
|
|
66
68
|
|
|
67
69
|
def test_unkown_extension(self):
|
|
68
|
-
assert guess_format(
|
|
70
|
+
assert guess_format("resource.unknonn") is None
|
|
69
71
|
|
|
70
72
|
def test_unkown_mime(self):
|
|
71
|
-
assert guess_format(
|
|
73
|
+
assert guess_format("unknown/mime") is None
|
udata/tests/test_routing.py
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
|
-
import pytest
|
|
2
|
-
|
|
3
|
-
from bson import ObjectId
|
|
4
1
|
from uuid import uuid4
|
|
5
2
|
|
|
3
|
+
import pytest
|
|
4
|
+
from bson import ObjectId
|
|
6
5
|
from flask import url_for
|
|
7
6
|
|
|
8
7
|
from udata import routing
|
|
9
|
-
from udata.core.spatial.models import GeoZone
|
|
10
8
|
from udata.core.spatial.factories import GeoZoneFactory
|
|
9
|
+
from udata.core.spatial.models import GeoZone
|
|
11
10
|
from udata.mongo import db
|
|
12
11
|
from udata.mongo.slug_fields import SlugFollow
|
|
13
12
|
from udata.tests.helpers import assert200, assert404, assert_redirects
|
|
@@ -16,33 +15,32 @@ from udata.tests.helpers import assert200, assert404, assert_redirects
|
|
|
16
15
|
class UUIDConverterTest:
|
|
17
16
|
@pytest.fixture(autouse=True)
|
|
18
17
|
def setup(self, app):
|
|
19
|
-
|
|
20
|
-
@app.route('/uuid/<uuid:uuid>')
|
|
18
|
+
@app.route("/uuid/<uuid:uuid>")
|
|
21
19
|
def uuid_tester(uuid):
|
|
22
|
-
return
|
|
20
|
+
return "ok"
|
|
23
21
|
|
|
24
22
|
def test_serialize_uuid_to_url(self):
|
|
25
23
|
uuid = uuid4()
|
|
26
|
-
url = url_for(
|
|
27
|
-
assert url ==
|
|
24
|
+
url = url_for("uuid_tester", uuid=uuid)
|
|
25
|
+
assert url == "/uuid/{0}".format(str(uuid))
|
|
28
26
|
|
|
29
27
|
def test_serialize_string_uuid_to_url(self):
|
|
30
28
|
uuid = uuid4()
|
|
31
|
-
url = url_for(
|
|
32
|
-
assert url ==
|
|
29
|
+
url = url_for("uuid_tester", uuid=str(uuid))
|
|
30
|
+
assert url == "/uuid/{0}".format(str(uuid))
|
|
33
31
|
|
|
34
32
|
def test_resolve_uuid(self, client):
|
|
35
33
|
uuid = uuid4()
|
|
36
|
-
url =
|
|
34
|
+
url = "/uuid/{0}".format(str(uuid))
|
|
37
35
|
assert200(client.get(url))
|
|
38
36
|
|
|
39
37
|
def test_resolve_uuid_with_spaces(self, client):
|
|
40
38
|
uuid = uuid4()
|
|
41
|
-
url =
|
|
39
|
+
url = "/uuid/{0} ".format(str(uuid))
|
|
42
40
|
assert200(client.get(url))
|
|
43
41
|
|
|
44
42
|
def test_bad_uuid_is_404(self, client):
|
|
45
|
-
assert404(client.get(
|
|
43
|
+
assert404(client.get("/uuid/bad"))
|
|
46
44
|
|
|
47
45
|
|
|
48
46
|
class Tester(db.Document):
|
|
@@ -69,53 +67,53 @@ class RedirectTesterConverter(routing.ModelConverter):
|
|
|
69
67
|
model = RedirectTester
|
|
70
68
|
|
|
71
69
|
|
|
72
|
-
@pytest.mark.usefixtures(
|
|
70
|
+
@pytest.mark.usefixtures("clean_db")
|
|
73
71
|
class ModelConverterMixin:
|
|
74
72
|
@pytest.fixture(autouse=True)
|
|
75
73
|
def setup(self, app):
|
|
76
|
-
app.url_map.converters[
|
|
74
|
+
app.url_map.converters["tester"] = self.converter
|
|
77
75
|
|
|
78
|
-
@app.route(
|
|
76
|
+
@app.route("/model/<tester:model>")
|
|
79
77
|
def model_tester(model):
|
|
80
78
|
assert isinstance(model, self.model)
|
|
81
79
|
return str(model.id)
|
|
82
80
|
|
|
83
81
|
def test_serialize_model_id_to_url(self):
|
|
84
82
|
tester = self.model.objects.create()
|
|
85
|
-
url = url_for(
|
|
86
|
-
assert url ==
|
|
83
|
+
url = url_for("model_tester", model=tester)
|
|
84
|
+
assert url == "/model/{0}".format(str(tester.id))
|
|
87
85
|
|
|
88
86
|
def test_serialize_model_slug_to_url(self):
|
|
89
|
-
tester = self.model.objects.create(slug=
|
|
90
|
-
url = url_for(
|
|
91
|
-
assert url ==
|
|
87
|
+
tester = self.model.objects.create(slug="slug")
|
|
88
|
+
url = url_for("model_tester", model=tester)
|
|
89
|
+
assert url == "/model/slug"
|
|
92
90
|
|
|
93
91
|
def test_serialize_object_id_to_url(self):
|
|
94
92
|
id = ObjectId()
|
|
95
|
-
url = url_for(
|
|
96
|
-
assert url ==
|
|
93
|
+
url = url_for("model_tester", model=id)
|
|
94
|
+
assert url == "/model/{0}".format(str(id))
|
|
97
95
|
|
|
98
96
|
def test_serialize_string_to_url(self):
|
|
99
|
-
slug =
|
|
100
|
-
url = url_for(
|
|
101
|
-
assert url ==
|
|
97
|
+
slug = "slug"
|
|
98
|
+
url = url_for("model_tester", model=slug)
|
|
99
|
+
assert url == "/model/slug"
|
|
102
100
|
|
|
103
101
|
def test_cant_serialize_model_to_url(self):
|
|
104
102
|
tester = self.model()
|
|
105
103
|
with pytest.raises(ValueError):
|
|
106
|
-
url_for(
|
|
104
|
+
url_for("model_tester", model=tester)
|
|
107
105
|
|
|
108
106
|
def test_resolve_model_from_id(self, client):
|
|
109
|
-
tester = self.model.objects.create(slug=
|
|
110
|
-
url =
|
|
107
|
+
tester = self.model.objects.create(slug="slug")
|
|
108
|
+
url = "/model/{0}".format(str(tester.id))
|
|
111
109
|
assert200(client.get(url))
|
|
112
110
|
|
|
113
111
|
def test_resolve_model_from_slug(self, client):
|
|
114
|
-
self.model.objects.create(slug=
|
|
115
|
-
assert200(client.get(
|
|
112
|
+
self.model.objects.create(slug="slug")
|
|
113
|
+
assert200(client.get("/model/slug"))
|
|
116
114
|
|
|
117
115
|
def test_model_not_found(self, client):
|
|
118
|
-
assert404(client.get(
|
|
116
|
+
assert404(client.get("/model/not-found"))
|
|
119
117
|
|
|
120
118
|
|
|
121
119
|
class SlugAsStringFieldTest(ModelConverterMixin):
|
|
@@ -123,42 +121,42 @@ class SlugAsStringFieldTest(ModelConverterMixin):
|
|
|
123
121
|
converter = TesterConverter
|
|
124
122
|
|
|
125
123
|
def test_quote_model_slug_with_unicode_to_url(self):
|
|
126
|
-
tester = Tester.objects.create(slug=
|
|
127
|
-
url = url_for(
|
|
128
|
-
assert url ==
|
|
124
|
+
tester = Tester.objects.create(slug="slüg")
|
|
125
|
+
url = url_for("model_tester", model=tester)
|
|
126
|
+
assert url == "/model/sl%C3%BCg"
|
|
129
127
|
|
|
130
128
|
def test_quote_unicode_string_to_url(self):
|
|
131
|
-
slug =
|
|
132
|
-
url = url_for(
|
|
133
|
-
assert url ==
|
|
129
|
+
slug = "slüg"
|
|
130
|
+
url = url_for("model_tester", model=slug)
|
|
131
|
+
assert url == "/model/sl%C3%BCg"
|
|
134
132
|
|
|
135
133
|
def test_match_utf8_slug(self, client):
|
|
136
|
-
slug =
|
|
134
|
+
slug = "slüg"
|
|
137
135
|
Tester.objects.create(slug=slug)
|
|
138
|
-
assert200(client.get(
|
|
136
|
+
assert200(client.get("/model/slüg"))
|
|
139
137
|
|
|
140
138
|
def test_match_normalized_utf8_slug(self, client):
|
|
141
|
-
slug =
|
|
139
|
+
slug = "slüg"
|
|
142
140
|
Tester.objects.create(slug=slug)
|
|
143
|
-
assert200(client.get(
|
|
141
|
+
assert200(client.get("/model/sl%C3%BCg"))
|
|
144
142
|
|
|
145
143
|
|
|
146
144
|
class AsSlugMixin(ModelConverterMixin):
|
|
147
145
|
def test_serialize_model_slug_with_unicode_to_url(self):
|
|
148
|
-
tester = self.model.objects.create(slug=
|
|
149
|
-
url = url_for(
|
|
150
|
-
assert url ==
|
|
146
|
+
tester = self.model.objects.create(slug="slüg")
|
|
147
|
+
url = url_for("model_tester", model=tester)
|
|
148
|
+
assert url == "/model/slug"
|
|
151
149
|
|
|
152
150
|
def test_serialize_unicode_string_to_url(self):
|
|
153
|
-
slug =
|
|
154
|
-
url = url_for(
|
|
155
|
-
assert url ==
|
|
151
|
+
slug = "slüg"
|
|
152
|
+
url = url_for("model_tester", model=slug)
|
|
153
|
+
assert url == "/model/slug"
|
|
156
154
|
|
|
157
155
|
def test_redirect_to_normalized_utf8_slug(self, client):
|
|
158
|
-
slug =
|
|
159
|
-
url = url_for(
|
|
156
|
+
slug = "slüg"
|
|
157
|
+
url = url_for("model_tester", model=slug)
|
|
160
158
|
self.model.objects.create(slug=slug)
|
|
161
|
-
assert_redirects(client.get(
|
|
159
|
+
assert_redirects(client.get("/model/slüg"), url)
|
|
162
160
|
|
|
163
161
|
|
|
164
162
|
class SlugAndIdTest(AsSlugMixin):
|
|
@@ -169,9 +167,9 @@ class SlugAndIdTest(AsSlugMixin):
|
|
|
169
167
|
"""Tests for url hijack. If a object is created with"""
|
|
170
168
|
"""an existing object's id as it's slug,"""
|
|
171
169
|
"""the endpoint should return the first one"""
|
|
172
|
-
tester = self.model.objects.create(slug=
|
|
170
|
+
tester = self.model.objects.create(slug="test_slug")
|
|
173
171
|
tester2 = self.model.objects.create(slug=str(tester.id))
|
|
174
|
-
model_url = url_for(
|
|
172
|
+
model_url = url_for("model_tester", model=tester2)
|
|
175
173
|
model_id = client.get(model_url)
|
|
176
174
|
assert model_id.get_data() != str(tester2.id)
|
|
177
175
|
|
|
@@ -181,13 +179,13 @@ class SlugAsSlugFieldTest(AsSlugMixin):
|
|
|
181
179
|
converter = SlugTesterConverter
|
|
182
180
|
|
|
183
181
|
def test_renaming(self, client):
|
|
184
|
-
tester = self.model.objects.create(slug=
|
|
185
|
-
old_url = url_for(
|
|
182
|
+
tester = self.model.objects.create(slug="old")
|
|
183
|
+
old_url = url_for("model_tester", model=tester)
|
|
186
184
|
assert200(client.get(old_url))
|
|
187
185
|
|
|
188
|
-
tester.slug =
|
|
186
|
+
tester.slug = "new"
|
|
189
187
|
tester.save()
|
|
190
|
-
new_url = url_for(
|
|
188
|
+
new_url = url_for("model_tester", model=tester)
|
|
191
189
|
assert200(client.get(new_url))
|
|
192
190
|
assert404(client.get(old_url))
|
|
193
191
|
|
|
@@ -197,53 +195,53 @@ class SlugAsSLugFieldWithFollowTest(AsSlugMixin):
|
|
|
197
195
|
converter = RedirectTesterConverter
|
|
198
196
|
|
|
199
197
|
def test_renaming_redirect(self, client):
|
|
200
|
-
tester = self.model.objects.create(slug=
|
|
201
|
-
old_url = url_for(
|
|
198
|
+
tester = self.model.objects.create(slug="old")
|
|
199
|
+
old_url = url_for("model_tester", model=tester)
|
|
202
200
|
assert200(client.get(old_url))
|
|
203
201
|
|
|
204
|
-
tester.slug =
|
|
202
|
+
tester.slug = "new"
|
|
205
203
|
tester.save().reload()
|
|
206
204
|
|
|
207
|
-
new_url = url_for(
|
|
205
|
+
new_url = url_for("model_tester", model=tester)
|
|
208
206
|
assert200(client.get(new_url))
|
|
209
207
|
assert_redirects(client.get(old_url), new_url)
|
|
210
208
|
|
|
211
209
|
def test_multiple_renaming_redirect(self, client):
|
|
212
|
-
tester = self.model.objects.create(slug=
|
|
213
|
-
first_url = url_for(
|
|
210
|
+
tester = self.model.objects.create(slug="first")
|
|
211
|
+
first_url = url_for("model_tester", model=tester)
|
|
214
212
|
|
|
215
|
-
tester.slug =
|
|
213
|
+
tester.slug = "second"
|
|
216
214
|
tester.save().reload()
|
|
217
|
-
second_url = url_for(
|
|
215
|
+
second_url = url_for("model_tester", model=tester)
|
|
218
216
|
assert200(client.get(second_url))
|
|
219
217
|
assert_redirects(client.get(first_url), second_url)
|
|
220
218
|
|
|
221
|
-
tester.slug =
|
|
219
|
+
tester.slug = "last"
|
|
222
220
|
tester.save().reload()
|
|
223
|
-
last_url = url_for(
|
|
221
|
+
last_url = url_for("model_tester", model=tester)
|
|
224
222
|
assert200(client.get(last_url))
|
|
225
223
|
assert_redirects(client.get(first_url), last_url)
|
|
226
224
|
assert_redirects(client.get(second_url), last_url)
|
|
227
225
|
|
|
228
226
|
def test_last_slug_has_priority(self, client):
|
|
229
|
-
tester = self.model.objects.create(slug=
|
|
230
|
-
first_url = url_for(
|
|
227
|
+
tester = self.model.objects.create(slug="first")
|
|
228
|
+
first_url = url_for("model_tester", model=tester)
|
|
231
229
|
|
|
232
|
-
tester.slug =
|
|
230
|
+
tester.slug = "second"
|
|
233
231
|
tester.save().reload()
|
|
234
|
-
second_url = url_for(
|
|
232
|
+
second_url = url_for("model_tester", model=tester)
|
|
235
233
|
|
|
236
|
-
tester.slug =
|
|
234
|
+
tester.slug = "third"
|
|
237
235
|
tester.save().reload()
|
|
238
|
-
third_url = url_for(
|
|
236
|
+
third_url = url_for("model_tester", model=tester)
|
|
239
237
|
|
|
240
|
-
new_tester = self.model.objects.create(slug=
|
|
238
|
+
new_tester = self.model.objects.create(slug="second")
|
|
241
239
|
# Second slug should not be redirected anymore
|
|
242
240
|
assert200(client.get(second_url))
|
|
243
241
|
|
|
244
|
-
new_tester.slug =
|
|
242
|
+
new_tester.slug = "last"
|
|
245
243
|
new_tester.save().reload()
|
|
246
|
-
last_url = url_for(
|
|
244
|
+
last_url = url_for("model_tester", model=new_tester)
|
|
247
245
|
|
|
248
246
|
# Current state should be:
|
|
249
247
|
# - first redirects to third (tester)
|
|
@@ -259,16 +257,16 @@ class SlugAsSLugFieldWithFollowTest(AsSlugMixin):
|
|
|
259
257
|
assert_redirects(client.get(first_url), third_url)
|
|
260
258
|
|
|
261
259
|
def test_redirects_destroyed_on_object_deleted(self, client):
|
|
262
|
-
tester = self.model.objects.create(slug=
|
|
263
|
-
first_url = url_for(
|
|
260
|
+
tester = self.model.objects.create(slug="first")
|
|
261
|
+
first_url = url_for("model_tester", model=tester)
|
|
264
262
|
|
|
265
|
-
tester.slug =
|
|
263
|
+
tester.slug = "second"
|
|
266
264
|
tester.save().reload()
|
|
267
|
-
second_url = url_for(
|
|
265
|
+
second_url = url_for("model_tester", model=tester)
|
|
268
266
|
|
|
269
|
-
tester.slug =
|
|
267
|
+
tester.slug = "last"
|
|
270
268
|
tester.save().reload()
|
|
271
|
-
last_url = url_for(
|
|
269
|
+
last_url = url_for("model_tester", model=tester)
|
|
272
270
|
|
|
273
271
|
tester.delete()
|
|
274
272
|
assert404(client.get(first_url))
|
|
@@ -278,35 +276,33 @@ class SlugAsSLugFieldWithFollowTest(AsSlugMixin):
|
|
|
278
276
|
assert SlugFollow.objects.count() is 0
|
|
279
277
|
|
|
280
278
|
|
|
281
|
-
@pytest.mark.usefixtures(
|
|
282
|
-
@pytest.mark.options(TERRITORY_DEFAULT_PREFIX=
|
|
279
|
+
@pytest.mark.usefixtures("clean_db")
|
|
280
|
+
@pytest.mark.options(TERRITORY_DEFAULT_PREFIX="fr") # Not implemented
|
|
283
281
|
class TerritoryConverterTest:
|
|
284
|
-
|
|
285
282
|
@pytest.fixture(autouse=True)
|
|
286
283
|
def setup(self, app):
|
|
287
|
-
|
|
288
|
-
@app.route('/territory/<territory:territory>')
|
|
284
|
+
@app.route("/territory/<territory:territory>")
|
|
289
285
|
def territory_tester(territory):
|
|
290
286
|
assert isinstance(territory, GeoZone)
|
|
291
287
|
return territory.id
|
|
292
288
|
|
|
293
289
|
def test_serialize_zone_with_validity(self):
|
|
294
290
|
zone = GeoZoneFactory()
|
|
295
|
-
url = url_for(
|
|
296
|
-
expected =
|
|
291
|
+
url = url_for("territory_tester", territory=zone)
|
|
292
|
+
expected = "/territory/{level}/{code}/{slug}"
|
|
297
293
|
assert url == expected.format(**zone._data)
|
|
298
294
|
|
|
299
295
|
def test_resolve_zone_without_optional_slug(self, client):
|
|
300
296
|
zone = GeoZoneFactory()
|
|
301
|
-
url =
|
|
297
|
+
url = "/territory/{level}/{code}/"
|
|
302
298
|
response = client.get(url.format(**zone._data))
|
|
303
299
|
assert200(response)
|
|
304
300
|
|
|
305
301
|
def test_resolve_zone_without_slug_nor_trailing_slash(self, client):
|
|
306
302
|
zone = GeoZoneFactory()
|
|
307
|
-
url =
|
|
303
|
+
url = "/territory/{level}/{code}"
|
|
308
304
|
response = client.get(url.format(**zone._data))
|
|
309
305
|
assert200(response)
|
|
310
306
|
|
|
311
307
|
def test_model_not_found(self, client):
|
|
312
|
-
assert404(client.get(
|
|
308
|
+
assert404(client.get("/territory/l/c"))
|