udata 9.1.2.dev30355__py2.py3-none-any.whl → 9.1.2.dev30382__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 +135 -124
- 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 +56 -54
- 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/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/static/chunks/{11.e9b9ca1f3e03d4020377.js → 11.52e531c19f8de80c00cf.js} +3 -3
- udata/static/chunks/{11.e9b9ca1f3e03d4020377.js.map → 11.52e531c19f8de80c00cf.js.map} +1 -1
- udata/static/chunks/{13.038c0d9aa0dfa0181c4b.js → 13.c3343a7f1070061c0e10.js} +2 -2
- udata/static/chunks/{13.038c0d9aa0dfa0181c4b.js.map → 13.c3343a7f1070061c0e10.js.map} +1 -1
- udata/static/chunks/{16.0baa2b64a74a2dcde25c.js → 16.8fa42440ad75ca172e6d.js} +2 -2
- udata/static/chunks/{16.0baa2b64a74a2dcde25c.js.map → 16.8fa42440ad75ca172e6d.js.map} +1 -1
- udata/static/chunks/{19.350a9f150b074b4ecefa.js → 19.9c6c8412729cd6d59cfa.js} +3 -3
- udata/static/chunks/{19.350a9f150b074b4ecefa.js.map → 19.9c6c8412729cd6d59cfa.js.map} +1 -1
- udata/static/chunks/{5.6ebbce2b9b3e696d3da5.js → 5.71d15c2e4f21feee2a9a.js} +3 -3
- udata/static/chunks/{5.6ebbce2b9b3e696d3da5.js.map → 5.71d15c2e4f21feee2a9a.js.map} +1 -1
- udata/static/chunks/{6.d8a5f7b017bcbd083641.js → 6.9139dc098b8ea640b890.js} +3 -3
- udata/static/chunks/{6.d8a5f7b017bcbd083641.js.map → 6.9139dc098b8ea640b890.js.map} +1 -1
- udata/static/common.js +1 -1
- udata/static/common.js.map +1 -1
- 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 +5 -6
- udata/tests/api/test_auth_api.py +395 -321
- udata/tests/api/test_base_api.py +31 -33
- 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 +76 -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_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.dev30382.dist-info}/METADATA +3 -2
- udata-9.1.2.dev30382.dist-info/RECORD +704 -0
- udata-9.1.2.dev30355.dist-info/RECORD +0 -704
- {udata-9.1.2.dev30355.dist-info → udata-9.1.2.dev30382.dist-info}/LICENSE +0 -0
- {udata-9.1.2.dev30355.dist-info → udata-9.1.2.dev30382.dist-info}/WHEEL +0 -0
- {udata-9.1.2.dev30355.dist-info → udata-9.1.2.dev30382.dist-info}/entry_points.txt +0 -0
- {udata-9.1.2.dev30355.dist-info → udata-9.1.2.dev30382.dist-info}/top_level.txt +0 -0
udata/tests/test_model.py
CHANGED
|
@@ -1,21 +1,18 @@
|
|
|
1
|
-
import pytest
|
|
2
|
-
|
|
3
|
-
from uuid import uuid4, UUID
|
|
4
1
|
from datetime import date, datetime, timedelta
|
|
2
|
+
from uuid import UUID, uuid4
|
|
5
3
|
|
|
4
|
+
import pytest
|
|
6
5
|
from mongoengine.errors import ValidationError
|
|
7
6
|
from mongoengine.fields import BaseField
|
|
8
7
|
|
|
8
|
+
from udata.errors import ConfigError
|
|
9
9
|
from udata.i18n import _
|
|
10
|
-
from udata.settings import Defaults
|
|
11
10
|
from udata.models import Dataset
|
|
12
|
-
from udata.mongo import db, validate_config
|
|
13
|
-
from udata.
|
|
14
|
-
from udata.tests.helpers import
|
|
11
|
+
from udata.mongo import build_test_config, db, validate_config
|
|
12
|
+
from udata.settings import Defaults
|
|
13
|
+
from udata.tests.helpers import assert_equal_dates, assert_json_equal
|
|
15
14
|
|
|
16
|
-
pytestmark = [
|
|
17
|
-
pytest.mark.usefixtures('clean_db')
|
|
18
|
-
]
|
|
15
|
+
pytestmark = [pytest.mark.usefixtures("clean_db")]
|
|
19
16
|
|
|
20
17
|
|
|
21
18
|
class UUIDTester(db.Document):
|
|
@@ -28,15 +25,15 @@ class UUIDAsIdTester(db.Document):
|
|
|
28
25
|
|
|
29
26
|
class SlugTester(db.Document):
|
|
30
27
|
title = db.StringField()
|
|
31
|
-
slug = db.SlugField(populate_from=
|
|
28
|
+
slug = db.SlugField(populate_from="title", max_length=1000)
|
|
32
29
|
meta = {
|
|
33
|
-
|
|
30
|
+
"allow_inheritance": True,
|
|
34
31
|
}
|
|
35
32
|
|
|
36
33
|
|
|
37
34
|
class SlugUpdateTester(db.Document):
|
|
38
35
|
title = db.StringField()
|
|
39
|
-
slug = db.SlugField(populate_from=
|
|
36
|
+
slug = db.SlugField(populate_from="title", update=True)
|
|
40
37
|
|
|
41
38
|
|
|
42
39
|
class DateTester(db.Document):
|
|
@@ -73,13 +70,13 @@ class PrivateURLTester(db.Document):
|
|
|
73
70
|
|
|
74
71
|
class AutoUUIDFieldTest:
|
|
75
72
|
def test_auto_populate(self):
|
|
76
|
-
|
|
73
|
+
"""AutoUUIDField should populate itself if not set"""
|
|
77
74
|
obj = UUIDTester()
|
|
78
75
|
assert obj.uuid is not None
|
|
79
76
|
assert isinstance(obj.uuid, UUID)
|
|
80
77
|
|
|
81
78
|
def test_do_not_overwrite(self):
|
|
82
|
-
|
|
79
|
+
"""AutoUUIDField shouldn't populate itself if a value is already set"""
|
|
83
80
|
uuid = uuid4()
|
|
84
81
|
obj = UUIDTester(uuid=uuid)
|
|
85
82
|
assert obj.uuid == uuid
|
|
@@ -106,143 +103,143 @@ class AutoUUIDFieldTest:
|
|
|
106
103
|
|
|
107
104
|
class SlugFieldTest:
|
|
108
105
|
def test_validate(self):
|
|
109
|
-
|
|
106
|
+
"""SlugField should validate if not set"""
|
|
110
107
|
obj = SlugTester(title="A Title")
|
|
111
108
|
assert obj.slug is None
|
|
112
109
|
obj.validate()
|
|
113
110
|
|
|
114
111
|
def test_populate(self):
|
|
115
|
-
|
|
112
|
+
"""SlugField should populate itself on save if not set"""
|
|
116
113
|
obj = SlugTester(title="A Title")
|
|
117
114
|
assert obj.slug is None
|
|
118
115
|
obj.save()
|
|
119
|
-
assert obj.slug ==
|
|
116
|
+
assert obj.slug == "a-title"
|
|
120
117
|
|
|
121
118
|
def test_populate_uuid(self):
|
|
122
|
-
|
|
119
|
+
"""SlugField should detect valid uuid"""
|
|
123
120
|
uuid = uuid4()
|
|
124
121
|
obj = SlugTester(title=str(uuid))
|
|
125
122
|
obj.save()
|
|
126
123
|
assert obj.slug == "{}{}".format(str(uuid), "-uuid")
|
|
127
124
|
|
|
128
125
|
def test_populate_next(self):
|
|
129
|
-
|
|
126
|
+
"""SlugField should not keep other fields value"""
|
|
130
127
|
obj = SlugTester.objects.create(title="A Title")
|
|
131
|
-
obj.slug =
|
|
128
|
+
obj.slug = "fake"
|
|
132
129
|
obj = SlugTester.objects.create(title="Another title")
|
|
133
|
-
assert obj.slug ==
|
|
130
|
+
assert obj.slug == "another-title"
|
|
134
131
|
|
|
135
132
|
def test_populate_parallel(self):
|
|
136
|
-
|
|
133
|
+
"""SlugField should not take other instance values"""
|
|
137
134
|
obj1 = SlugTester.objects.create(title="A Title")
|
|
138
135
|
obj = SlugTester.objects.create(title="Another title")
|
|
139
|
-
obj1.slug =
|
|
140
|
-
assert obj.slug ==
|
|
136
|
+
obj1.slug = "fake"
|
|
137
|
+
assert obj.slug == "another-title"
|
|
141
138
|
|
|
142
139
|
def test_no_populate(self):
|
|
143
|
-
|
|
144
|
-
obj = SlugTester(title=
|
|
140
|
+
"""SlugField should not populate itself if a value is set"""
|
|
141
|
+
obj = SlugTester(title="A Title", slug="a-slug")
|
|
145
142
|
obj.save()
|
|
146
|
-
assert obj.slug ==
|
|
143
|
+
assert obj.slug == "a-slug"
|
|
147
144
|
|
|
148
145
|
def test_populate_update(self):
|
|
149
|
-
|
|
146
|
+
"""SlugField should populate itself on save and update"""
|
|
150
147
|
obj = SlugUpdateTester(title="A Title")
|
|
151
148
|
obj.save()
|
|
152
|
-
assert obj.slug ==
|
|
153
|
-
obj.title =
|
|
149
|
+
assert obj.slug == "a-title"
|
|
150
|
+
obj.title = "Title"
|
|
154
151
|
obj.save()
|
|
155
|
-
assert obj.slug ==
|
|
152
|
+
assert obj.slug == "title"
|
|
156
153
|
|
|
157
154
|
def test_no_populate_update(self):
|
|
158
|
-
|
|
155
|
+
"""SlugField should not populate itself if a value is set"""
|
|
159
156
|
obj = SlugUpdateTester(title="A Title")
|
|
160
157
|
obj.save()
|
|
161
|
-
assert obj.slug ==
|
|
162
|
-
obj.title =
|
|
163
|
-
obj.slug =
|
|
158
|
+
assert obj.slug == "a-title"
|
|
159
|
+
obj.title = "Title"
|
|
160
|
+
obj.slug = "other"
|
|
164
161
|
obj.save()
|
|
165
|
-
assert obj.slug ==
|
|
162
|
+
assert obj.slug == "other"
|
|
166
163
|
|
|
167
164
|
def test_unchanged(self):
|
|
168
|
-
|
|
165
|
+
"""SlugField should not change on save if not needed"""
|
|
169
166
|
obj = SlugTester(title="A Title")
|
|
170
167
|
assert obj.slug is None
|
|
171
168
|
obj.save()
|
|
172
|
-
assert obj.slug ==
|
|
169
|
+
assert obj.slug == "a-title"
|
|
173
170
|
obj.save()
|
|
174
|
-
assert obj.slug ==
|
|
171
|
+
assert obj.slug == "a-title"
|
|
175
172
|
|
|
176
173
|
def test_changed_no_update(self):
|
|
177
|
-
|
|
174
|
+
"""SlugField should not update slug if update=False"""
|
|
178
175
|
obj = SlugTester(title="A Title")
|
|
179
176
|
obj.save()
|
|
180
|
-
assert obj.slug ==
|
|
181
|
-
obj.title =
|
|
177
|
+
assert obj.slug == "a-title"
|
|
178
|
+
obj.title = "Title"
|
|
182
179
|
obj.save()
|
|
183
|
-
assert obj.slug ==
|
|
180
|
+
assert obj.slug == "a-title"
|
|
184
181
|
|
|
185
182
|
def test_manually_set(self):
|
|
186
|
-
|
|
187
|
-
obj = SlugTester(title=
|
|
188
|
-
assert obj.slug ==
|
|
183
|
+
"""SlugField can be manually set"""
|
|
184
|
+
obj = SlugTester(title="A title", slug="a-slug")
|
|
185
|
+
assert obj.slug == "a-slug"
|
|
189
186
|
obj.save()
|
|
190
|
-
assert obj.slug ==
|
|
187
|
+
assert obj.slug == "a-slug"
|
|
191
188
|
|
|
192
189
|
def test_work_accross_inheritance(self):
|
|
193
|
-
|
|
194
|
-
obj = SlugTester.objects.create(title=
|
|
195
|
-
inherited = InheritedSlugTester.objects.create(title=
|
|
190
|
+
"""SlugField should ensure uniqueness accross inheritance"""
|
|
191
|
+
obj = SlugTester.objects.create(title="title")
|
|
192
|
+
inherited = InheritedSlugTester.objects.create(title="title")
|
|
196
193
|
assert obj.slug != inherited.slug
|
|
197
194
|
|
|
198
195
|
def test_crop(self):
|
|
199
|
-
|
|
200
|
-
obj = SlugTester(title=
|
|
196
|
+
"""SlugField should truncate itself on save if not set"""
|
|
197
|
+
obj = SlugTester(title="x" * (SlugTester.slug.max_length + 1))
|
|
201
198
|
obj.save()
|
|
202
199
|
assert len(obj.title) == SlugTester.slug.max_length + 1
|
|
203
200
|
assert len(obj.slug) == SlugTester.slug.max_length
|
|
204
201
|
|
|
205
202
|
def test_crop_with_index(self):
|
|
206
|
-
|
|
207
|
-
first_obj = SlugTester(title=
|
|
203
|
+
"""SlugField should truncate itself to keep room for index suffix if not unique"""
|
|
204
|
+
first_obj = SlugTester(title="x" * (SlugTester.slug.max_length + 1))
|
|
208
205
|
first_obj.save()
|
|
209
206
|
assert len(first_obj.slug) == SlugTester.slug.max_length
|
|
210
|
-
assert first_obj.slug.endswith(
|
|
207
|
+
assert first_obj.slug.endswith("x")
|
|
211
208
|
# Try adding a second obj with same title with a slug already at max_length
|
|
212
|
-
second_obj = SlugTester(title=
|
|
209
|
+
second_obj = SlugTester(title="x" * (SlugTester.slug.max_length + 1))
|
|
213
210
|
second_obj.save()
|
|
214
211
|
assert len(second_obj.slug) == SlugTester.slug.max_length
|
|
215
|
-
assert second_obj.slug.endswith(
|
|
212
|
+
assert second_obj.slug.endswith("-1")
|
|
216
213
|
# We could even have 10+ obj with the same title that needs index suffix
|
|
217
|
-
[SlugTester(title=
|
|
218
|
-
last_obj = SlugTester(title=
|
|
214
|
+
[SlugTester(title="x" * (SlugTester.slug.max_length + 1)).save() for i in range(8)]
|
|
215
|
+
last_obj = SlugTester(title="x" * (SlugTester.slug.max_length + 1))
|
|
219
216
|
last_obj.save()
|
|
220
217
|
assert len(last_obj.slug) == SlugTester.slug.max_length
|
|
221
|
-
assert last_obj.slug.endswith(
|
|
218
|
+
assert last_obj.slug.endswith("-10")
|
|
222
219
|
|
|
223
220
|
def test_multiple_spaces(self):
|
|
224
221
|
field = db.SlugField()
|
|
225
|
-
assert field.slugify(
|
|
222
|
+
assert field.slugify("a b") == "a-b"
|
|
226
223
|
|
|
227
224
|
def test_lower_case_default(self):
|
|
228
225
|
field = db.SlugField()
|
|
229
|
-
assert field.slugify(
|
|
226
|
+
assert field.slugify("ABC") == "abc"
|
|
230
227
|
|
|
231
228
|
def test_lower_case_false(self):
|
|
232
229
|
field = db.SlugField(lower_case=False)
|
|
233
|
-
assert field.slugify(
|
|
230
|
+
assert field.slugify("AbC") == "AbC"
|
|
234
231
|
|
|
235
232
|
def test_custom_separator(self):
|
|
236
|
-
field = db.SlugField(separator=
|
|
237
|
-
assert field.slugify(
|
|
233
|
+
field = db.SlugField(separator="+")
|
|
234
|
+
assert field.slugify("a b") == "a+b"
|
|
238
235
|
|
|
239
236
|
def test_is_stripped(self):
|
|
240
237
|
field = db.SlugField()
|
|
241
|
-
assert field.slugify(
|
|
238
|
+
assert field.slugify(" ab ") == "ab"
|
|
242
239
|
|
|
243
240
|
def test_special_chars_are_normalized(self):
|
|
244
241
|
field = db.SlugField()
|
|
245
|
-
assert field.slugify(
|
|
242
|
+
assert field.slugify("à-€-ü") == "a-eur-u"
|
|
246
243
|
|
|
247
244
|
|
|
248
245
|
class DateFieldTest:
|
|
@@ -270,7 +267,7 @@ class DateFieldTest:
|
|
|
270
267
|
assert obj.a_date == the_date
|
|
271
268
|
|
|
272
269
|
def test_not_valid(self):
|
|
273
|
-
obj = DateTester(a_date=
|
|
270
|
+
obj = DateTester(a_date="invalid")
|
|
274
271
|
with pytest.raises(ValidationError):
|
|
275
272
|
obj.save()
|
|
276
273
|
|
|
@@ -286,7 +283,7 @@ class DateRangeFieldTest:
|
|
|
286
283
|
def test_both_valid(self):
|
|
287
284
|
start = date(1984, 6, 6)
|
|
288
285
|
end = date(1984, 6, 7)
|
|
289
|
-
obj = DateRangeTester(temporal={
|
|
286
|
+
obj = DateRangeTester(temporal={"start": start, "end": end})
|
|
290
287
|
assert obj.temporal.start == start
|
|
291
288
|
assert obj.temporal.end == end
|
|
292
289
|
obj.save()
|
|
@@ -297,7 +294,7 @@ class DateRangeFieldTest:
|
|
|
297
294
|
def test_both_valid_but_reversed(self):
|
|
298
295
|
start = date(1984, 6, 6)
|
|
299
296
|
end = date(1984, 6, 7)
|
|
300
|
-
obj = DateRangeTester(temporal={
|
|
297
|
+
obj = DateRangeTester(temporal={"start": end, "end": start})
|
|
301
298
|
assert obj.temporal.start == end
|
|
302
299
|
assert obj.temporal.end == start
|
|
303
300
|
obj.save()
|
|
@@ -307,7 +304,7 @@ class DateRangeFieldTest:
|
|
|
307
304
|
|
|
308
305
|
def test_only_start(self):
|
|
309
306
|
start = date(1984, 6, 6)
|
|
310
|
-
obj = DateRangeTester(temporal={
|
|
307
|
+
obj = DateRangeTester(temporal={"start": start})
|
|
311
308
|
assert obj.temporal.start == start
|
|
312
309
|
assert obj.temporal.end is None
|
|
313
310
|
obj.save()
|
|
@@ -317,7 +314,7 @@ class DateRangeFieldTest:
|
|
|
317
314
|
|
|
318
315
|
def test_only_end(self):
|
|
319
316
|
end = date(1984, 6, 7)
|
|
320
|
-
obj = DateRangeTester(temporal={
|
|
317
|
+
obj = DateRangeTester(temporal={"end": end})
|
|
321
318
|
assert obj.temporal.start is None
|
|
322
319
|
assert obj.temporal.end == end
|
|
323
320
|
obj.save()
|
|
@@ -326,7 +323,7 @@ class DateRangeFieldTest:
|
|
|
326
323
|
assert obj.temporal.end == end
|
|
327
324
|
|
|
328
325
|
def test_not_valid(self):
|
|
329
|
-
obj = DateRangeTester(temporal={
|
|
326
|
+
obj = DateRangeTester(temporal={"start": "wrong"})
|
|
330
327
|
with pytest.raises(ValidationError):
|
|
331
328
|
obj.save()
|
|
332
329
|
|
|
@@ -338,7 +335,7 @@ class DateRangeFieldTest:
|
|
|
338
335
|
|
|
339
336
|
def test_only_start_when_required(self):
|
|
340
337
|
start = date(1984, 6, 6)
|
|
341
|
-
obj = RequiredDateRangeTester(temporal={
|
|
338
|
+
obj = RequiredDateRangeTester(temporal={"start": start})
|
|
342
339
|
assert obj.temporal.start == start
|
|
343
340
|
assert obj.temporal.end is None
|
|
344
341
|
obj.save()
|
|
@@ -348,7 +345,7 @@ class DateRangeFieldTest:
|
|
|
348
345
|
|
|
349
346
|
def test_only_end_when_required(self):
|
|
350
347
|
end = date(1984, 6, 7)
|
|
351
|
-
obj = RequiredDateRangeTester(temporal={
|
|
348
|
+
obj = RequiredDateRangeTester(temporal={"end": end})
|
|
352
349
|
assert obj.temporal.start is None
|
|
353
350
|
assert obj.temporal.end == end
|
|
354
351
|
obj.save()
|
|
@@ -366,26 +363,26 @@ class URLFieldTest:
|
|
|
366
363
|
assert obj.url is None
|
|
367
364
|
|
|
368
365
|
def test_not_valid(self):
|
|
369
|
-
obj = URLTester(url=
|
|
366
|
+
obj = URLTester(url="invalid")
|
|
370
367
|
with pytest.raises(ValidationError, match=_('Invalid URL "{url}"').format(url="invalid")):
|
|
371
368
|
obj.save()
|
|
372
369
|
|
|
373
370
|
def test_strip_spaces(self):
|
|
374
|
-
url =
|
|
371
|
+
url = " https://www.somewhere.com/with/spaces/ "
|
|
375
372
|
obj = URLTester(url=url)
|
|
376
373
|
obj.save().reload()
|
|
377
374
|
assert obj.url == url.strip()
|
|
378
375
|
|
|
379
376
|
def test_handle_unicode(self):
|
|
380
|
-
url =
|
|
377
|
+
url = "https://www.somewhère.com/with/accënts/"
|
|
381
378
|
obj = URLTester(url=url)
|
|
382
379
|
obj.save().reload()
|
|
383
380
|
assert obj.url == url
|
|
384
381
|
|
|
385
382
|
def test_public_private(self):
|
|
386
|
-
url =
|
|
383
|
+
url = "http://10.10.0.2/path/"
|
|
387
384
|
PrivateURLTester(url=url).save()
|
|
388
|
-
with pytest.raises(ValidationError, match=_(
|
|
385
|
+
with pytest.raises(ValidationError, match=_("is a private URL")):
|
|
389
386
|
URLTester(url=url).save()
|
|
390
387
|
|
|
391
388
|
|
|
@@ -411,8 +408,7 @@ class DatetimedTest:
|
|
|
411
408
|
def test_save_last_modified_instance(self):
|
|
412
409
|
now = datetime.utcnow()
|
|
413
410
|
earlier = now - timedelta(days=1)
|
|
414
|
-
datetimed = DatetimedTester.objects.create(
|
|
415
|
-
created_at=earlier, last_modified=earlier)
|
|
411
|
+
datetimed = DatetimedTester.objects.create(created_at=earlier, last_modified=earlier)
|
|
416
412
|
|
|
417
413
|
datetimed.save()
|
|
418
414
|
datetimed.reload()
|
|
@@ -459,14 +455,16 @@ class ExtrasFieldTest:
|
|
|
459
455
|
now = datetime.utcnow()
|
|
460
456
|
today = date.today()
|
|
461
457
|
|
|
462
|
-
tester = Tester(
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
458
|
+
tester = Tester(
|
|
459
|
+
extras={
|
|
460
|
+
"string": "string",
|
|
461
|
+
"integer": 5,
|
|
462
|
+
"float": 5.5,
|
|
463
|
+
"datetime": now,
|
|
464
|
+
"date": today,
|
|
465
|
+
"bool": True,
|
|
466
|
+
}
|
|
467
|
+
)
|
|
470
468
|
tester.validate()
|
|
471
469
|
|
|
472
470
|
def test_can_only_register_db_type(self):
|
|
@@ -474,109 +472,120 @@ class ExtrasFieldTest:
|
|
|
474
472
|
extras = db.ExtrasField()
|
|
475
473
|
|
|
476
474
|
with pytest.raises(TypeError):
|
|
477
|
-
Tester.extras.register(
|
|
478
|
-
|
|
479
|
-
@pytest.mark.parametrize(
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
475
|
+
Tester.extras.register("test", datetime)
|
|
476
|
+
|
|
477
|
+
@pytest.mark.parametrize(
|
|
478
|
+
"dbtype,value",
|
|
479
|
+
[
|
|
480
|
+
(db.IntField, 42),
|
|
481
|
+
(db.FloatField, 0.42),
|
|
482
|
+
(db.BooleanField, True),
|
|
483
|
+
(db.DateTimeField, datetime.utcnow()),
|
|
484
|
+
(db.DateField, date.today()),
|
|
485
|
+
],
|
|
486
|
+
)
|
|
486
487
|
def test_validate_registered_db_type(self, dbtype, value):
|
|
487
488
|
class Tester(db.Document):
|
|
488
489
|
extras = db.ExtrasField()
|
|
489
490
|
|
|
490
|
-
Tester.extras.register(
|
|
491
|
+
Tester.extras.register("test", dbtype)
|
|
491
492
|
|
|
492
|
-
Tester(extras={
|
|
493
|
+
Tester(extras={"test": value}).validate()
|
|
493
494
|
|
|
494
|
-
@pytest.mark.parametrize(
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
495
|
+
@pytest.mark.parametrize(
|
|
496
|
+
"dbtype,value",
|
|
497
|
+
[
|
|
498
|
+
(db.IntField, datetime.utcnow()),
|
|
499
|
+
(db.FloatField, datetime.utcnow()),
|
|
500
|
+
(db.BooleanField, 42),
|
|
501
|
+
(db.DateTimeField, 42),
|
|
502
|
+
(db.DateField, 42),
|
|
503
|
+
],
|
|
504
|
+
)
|
|
501
505
|
def test_fail_to_validate_wrong_type(self, dbtype, value):
|
|
502
506
|
class Tester(db.Document):
|
|
503
507
|
extras = db.ExtrasField()
|
|
504
508
|
|
|
505
|
-
Tester.extras.register(
|
|
509
|
+
Tester.extras.register("test", dbtype)
|
|
506
510
|
|
|
507
511
|
with pytest.raises(db.ValidationError):
|
|
508
|
-
Tester(extras={
|
|
512
|
+
Tester(extras={"test": value}).validate()
|
|
509
513
|
|
|
510
514
|
def test_validate_custom_type(self):
|
|
511
515
|
class Tester(db.Document):
|
|
512
516
|
extras = db.ExtrasField()
|
|
513
517
|
|
|
514
|
-
@Tester.extras(
|
|
518
|
+
@Tester.extras("test")
|
|
515
519
|
class Custom(BaseField):
|
|
516
520
|
def validate(self, value):
|
|
517
521
|
if not isinstance(value, dict):
|
|
518
|
-
raise db.ValidationError(
|
|
522
|
+
raise db.ValidationError("Should be a dict instance")
|
|
519
523
|
|
|
520
|
-
tester = Tester(extras={
|
|
524
|
+
tester = Tester(extras={"test": {}})
|
|
521
525
|
tester.validate()
|
|
522
526
|
|
|
523
527
|
def test_validate_registered_type_embedded_document(self):
|
|
524
528
|
class Tester(db.Document):
|
|
525
529
|
extras = db.ExtrasField()
|
|
526
530
|
|
|
527
|
-
@Tester.extras(
|
|
531
|
+
@Tester.extras("test")
|
|
528
532
|
class EmbeddedExtra(db.EmbeddedDocument):
|
|
529
533
|
name = db.StringField(required=True)
|
|
530
534
|
|
|
531
|
-
tester = Tester(extras={
|
|
535
|
+
tester = Tester(extras={"test": {}})
|
|
532
536
|
with pytest.raises(ValidationError):
|
|
533
537
|
tester.validate()
|
|
534
538
|
|
|
535
|
-
tester.extras[
|
|
539
|
+
tester.extras["test"] = {"name": "test"}
|
|
536
540
|
tester.validate()
|
|
537
541
|
|
|
538
|
-
tester.extras[
|
|
542
|
+
tester.extras["test"] = EmbeddedExtra(name="test")
|
|
539
543
|
tester.validate()
|
|
540
544
|
|
|
541
545
|
def test_is_json_serializable(self):
|
|
542
546
|
class Tester(db.Document):
|
|
543
547
|
extras = db.ExtrasField()
|
|
544
548
|
|
|
545
|
-
@Tester.extras(
|
|
549
|
+
@Tester.extras("embedded")
|
|
546
550
|
class EmbeddedExtra(db.EmbeddedDocument):
|
|
547
551
|
name = db.StringField(required=True)
|
|
548
552
|
|
|
549
|
-
tester = Tester(
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
553
|
+
tester = Tester(
|
|
554
|
+
extras={
|
|
555
|
+
"test": {"key": "value"},
|
|
556
|
+
"embedded": EmbeddedExtra(name="An embedded field"),
|
|
557
|
+
"string": "a value",
|
|
558
|
+
"integer": 5,
|
|
559
|
+
"float": 5.5,
|
|
560
|
+
}
|
|
561
|
+
)
|
|
562
|
+
|
|
563
|
+
assert_json_equal(
|
|
564
|
+
tester.extras,
|
|
565
|
+
{
|
|
566
|
+
"test": {"key": "value"},
|
|
567
|
+
"embedded": {"name": "An embedded field"},
|
|
568
|
+
"string": "a value",
|
|
569
|
+
"integer": 5,
|
|
570
|
+
"float": 5.5,
|
|
571
|
+
},
|
|
572
|
+
)
|
|
564
573
|
|
|
565
574
|
|
|
566
575
|
class ModelResolutionTest:
|
|
567
576
|
def test_resolve_exact_match(self):
|
|
568
|
-
assert db.resolve_model(
|
|
577
|
+
assert db.resolve_model("Dataset") == Dataset
|
|
569
578
|
|
|
570
579
|
def test_resolve_from_dict(self):
|
|
571
|
-
assert db.resolve_model({
|
|
580
|
+
assert db.resolve_model({"class": "Dataset"}) == Dataset
|
|
572
581
|
|
|
573
582
|
def test_raise_if_not_found(self):
|
|
574
583
|
with pytest.raises(ValueError):
|
|
575
|
-
db.resolve_model(
|
|
584
|
+
db.resolve_model("NotFound")
|
|
576
585
|
|
|
577
586
|
def test_raise_if_not_a_document(self):
|
|
578
587
|
with pytest.raises(ValueError):
|
|
579
|
-
db.resolve_model(
|
|
588
|
+
db.resolve_model("UDataMongoEngine")
|
|
580
589
|
|
|
581
590
|
def test_raise_if_none(self):
|
|
582
591
|
with pytest.raises(ValueError):
|
|
@@ -584,49 +593,47 @@ class ModelResolutionTest:
|
|
|
584
593
|
|
|
585
594
|
def test_raise_if_missing_class_entry(self):
|
|
586
595
|
with pytest.raises(ValueError):
|
|
587
|
-
db.resolve_model({
|
|
596
|
+
db.resolve_model({"field": "value"})
|
|
588
597
|
|
|
589
598
|
|
|
590
599
|
class MongoConfigTest:
|
|
591
600
|
def test_validate_default_value(self):
|
|
592
|
-
validate_config({
|
|
601
|
+
validate_config({"MONGODB_HOST": Defaults.MONGODB_HOST})
|
|
593
602
|
|
|
594
603
|
def test_validate_with_auth(self):
|
|
595
|
-
validate_config({
|
|
604
|
+
validate_config({"MONGODB_HOST": "mongodb://userid:password@somewhere.com:1234/mydb"})
|
|
596
605
|
|
|
597
606
|
def test_raise_exception_on_host_only(self):
|
|
598
607
|
with pytest.raises(ConfigError):
|
|
599
|
-
validate_config({
|
|
608
|
+
validate_config({"MONGODB_HOST": "somehost"})
|
|
600
609
|
|
|
601
610
|
def test_raise_exception_on_missing_db(self):
|
|
602
611
|
with pytest.raises(ConfigError):
|
|
603
|
-
validate_config({
|
|
612
|
+
validate_config({"MONGODB_HOST": "mongodb://somewhere.com:1234"})
|
|
604
613
|
with pytest.raises(ConfigError):
|
|
605
|
-
validate_config({
|
|
614
|
+
validate_config({"MONGODB_HOST": "mongodb://somewhere.com:1234/"})
|
|
606
615
|
|
|
607
616
|
def test_warn_on_deprecated_db_port(self):
|
|
608
617
|
with pytest.deprecated_call():
|
|
609
|
-
validate_config({
|
|
610
|
-
'MONGODB_PORT': 1234})
|
|
618
|
+
validate_config({"MONGODB_HOST": Defaults.MONGODB_HOST, "MONGODB_PORT": 1234})
|
|
611
619
|
with pytest.deprecated_call():
|
|
612
|
-
validate_config({
|
|
613
|
-
'MONGODB_DB': 'udata'})
|
|
620
|
+
validate_config({"MONGODB_HOST": Defaults.MONGODB_HOST, "MONGODB_DB": "udata"})
|
|
614
621
|
|
|
615
622
|
def test_build_test_config_with_MONGODB_HOST_TEST(self):
|
|
616
|
-
test_url =
|
|
617
|
-
config = {
|
|
623
|
+
test_url = "mongodb://somewhere.com:1234/test"
|
|
624
|
+
config = {"MONGODB_HOST_TEST": test_url}
|
|
618
625
|
build_test_config(config)
|
|
619
|
-
assert
|
|
620
|
-
assert config[
|
|
626
|
+
assert "MONGODB_HOST" in config
|
|
627
|
+
assert config["MONGODB_HOST"] == test_url
|
|
621
628
|
|
|
622
629
|
def test_build_test_config_without_MONGODB_HOST_TEST(self):
|
|
623
|
-
config = {
|
|
624
|
-
expected =
|
|
630
|
+
config = {"MONGODB_HOST": Defaults.MONGODB_HOST}
|
|
631
|
+
expected = "{0}-test".format(Defaults.MONGODB_HOST)
|
|
625
632
|
build_test_config(config)
|
|
626
|
-
assert config[
|
|
633
|
+
assert config["MONGODB_HOST"] == expected
|
|
627
634
|
|
|
628
635
|
def test_build_test_config_should_validate(self):
|
|
629
636
|
with pytest.raises(ConfigError):
|
|
630
|
-
test_url =
|
|
631
|
-
config = {
|
|
637
|
+
test_url = "mongodb://somewhere.com:1234"
|
|
638
|
+
config = {"MONGODB_HOST_TEST": test_url}
|
|
632
639
|
build_test_config(config)
|