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/frontend/test_csv.py
CHANGED
|
@@ -1,27 +1,22 @@
|
|
|
1
1
|
import re
|
|
2
2
|
from io import StringIO
|
|
3
|
-
|
|
4
|
-
import factory
|
|
5
|
-
|
|
6
3
|
from random import randint
|
|
7
4
|
|
|
5
|
+
import factory
|
|
8
6
|
from factory.mongoengine import MongoEngineFactory
|
|
7
|
+
from flask import Blueprint, url_for
|
|
9
8
|
|
|
10
|
-
from flask import url_for, Blueprint
|
|
11
|
-
|
|
12
|
-
from udata.mongo import db
|
|
13
9
|
from udata.frontend import csv
|
|
10
|
+
from udata.mongo import db
|
|
14
11
|
from udata.utils import faker
|
|
15
12
|
|
|
16
13
|
from . import FrontTestCase
|
|
17
14
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
RE_FILENAME = re.compile(
|
|
21
|
-
r'^(?P<basename>.*)-\d{4}-\d{2}-\d{2}-\d{2}-\d{2}\.csv$')
|
|
15
|
+
RE_ATTACHMENT = re.compile(r"^attachment; filename=(?P<filename>.*)$")
|
|
16
|
+
RE_FILENAME = re.compile(r"^(?P<basename>.*)-\d{4}-\d{2}-\d{2}-\d{2}-\d{2}\.csv$")
|
|
22
17
|
|
|
23
18
|
|
|
24
|
-
blueprint = Blueprint(
|
|
19
|
+
blueprint = Blueprint("testcsv", __name__)
|
|
25
20
|
|
|
26
21
|
|
|
27
22
|
class NestedFake(db.EmbeddedDocument):
|
|
@@ -39,12 +34,12 @@ class Fake(db.Document):
|
|
|
39
34
|
metrics = db.DictField()
|
|
40
35
|
|
|
41
36
|
__metrics_keys__ = [
|
|
42
|
-
|
|
43
|
-
|
|
37
|
+
"fake-metric-int",
|
|
38
|
+
"fake-metric-float",
|
|
44
39
|
]
|
|
45
40
|
|
|
46
41
|
def __str__(self):
|
|
47
|
-
return
|
|
42
|
+
return "fake"
|
|
48
43
|
|
|
49
44
|
def get_metrics(self):
|
|
50
45
|
return self.metrics
|
|
@@ -64,57 +59,56 @@ class FakeFactory(MongoEngineFactory):
|
|
|
64
59
|
|
|
65
60
|
title = factory.LazyAttribute(lambda o: faker.sentence())
|
|
66
61
|
description = factory.LazyAttribute(lambda o: faker.paragraph())
|
|
67
|
-
tags = factory.LazyAttribute(
|
|
68
|
-
lambda o: [faker.word() for _ in range(1, randint(1, 4))])
|
|
62
|
+
tags = factory.LazyAttribute(lambda o: [faker.word() for _ in range(1, randint(1, 4))])
|
|
69
63
|
sub = factory.SubFactory(NestedFactory)
|
|
70
64
|
|
|
71
65
|
|
|
72
66
|
class NestedAdapter(csv.NestedAdapter):
|
|
73
|
-
attribute =
|
|
67
|
+
attribute = "nested"
|
|
74
68
|
fields = (
|
|
75
|
-
|
|
76
|
-
|
|
69
|
+
"title",
|
|
70
|
+
"description",
|
|
77
71
|
)
|
|
78
72
|
nested_fields = (
|
|
79
|
-
|
|
80
|
-
(
|
|
73
|
+
"key",
|
|
74
|
+
("alias", "value"),
|
|
81
75
|
)
|
|
82
76
|
|
|
83
77
|
|
|
84
|
-
@blueprint.route(
|
|
78
|
+
@blueprint.route("/adapter.csv")
|
|
85
79
|
def from_adapter():
|
|
86
80
|
cls = csv.get_adapter(Fake)
|
|
87
81
|
adapter = cls(Fake.objects)
|
|
88
82
|
return csv.stream(adapter)
|
|
89
83
|
|
|
90
84
|
|
|
91
|
-
@blueprint.route(
|
|
85
|
+
@blueprint.route("/list.csv")
|
|
92
86
|
def from_list():
|
|
93
87
|
return csv.stream(list(Fake.objects))
|
|
94
88
|
|
|
95
89
|
|
|
96
|
-
@blueprint.route(
|
|
90
|
+
@blueprint.route("/queryset.csv")
|
|
97
91
|
def from_queryset():
|
|
98
92
|
qs = Fake.objects
|
|
99
93
|
assert isinstance(qs, db.BaseQuerySet)
|
|
100
94
|
return csv.stream(qs)
|
|
101
95
|
|
|
102
96
|
|
|
103
|
-
@blueprint.route(
|
|
97
|
+
@blueprint.route("/nested.csv")
|
|
104
98
|
def from_nested():
|
|
105
99
|
qs = Fake.objects
|
|
106
100
|
return csv.stream(NestedAdapter(qs))
|
|
107
101
|
|
|
108
102
|
|
|
109
|
-
@blueprint.route(
|
|
103
|
+
@blueprint.route("/with-basename.csv")
|
|
110
104
|
def with_basename():
|
|
111
105
|
cls = csv.get_adapter(Fake)
|
|
112
106
|
adapter = cls(Fake.objects)
|
|
113
|
-
return csv.stream(adapter,
|
|
107
|
+
return csv.stream(adapter, "test")
|
|
114
108
|
|
|
115
109
|
|
|
116
110
|
class CsvTest(FrontTestCase):
|
|
117
|
-
modules = [
|
|
111
|
+
modules = ["admin"]
|
|
118
112
|
|
|
119
113
|
def create_app(self):
|
|
120
114
|
app = super(CsvTest, self).create_app()
|
|
@@ -124,13 +118,13 @@ class CsvTest(FrontTestCase):
|
|
|
124
118
|
def test_adapter_fields_as_list(self):
|
|
125
119
|
@csv.adapter(Fake)
|
|
126
120
|
class Adapter(csv.Adapter):
|
|
127
|
-
fields = [
|
|
121
|
+
fields = ["title", "description"]
|
|
128
122
|
|
|
129
123
|
objects = FakeFactory.build_batch(3)
|
|
130
124
|
adapter = Adapter(objects)
|
|
131
125
|
|
|
132
126
|
header = adapter.header()
|
|
133
|
-
self.assertEqual(header, [
|
|
127
|
+
self.assertEqual(header, ["title", "description"])
|
|
134
128
|
|
|
135
129
|
rows = list(adapter.rows())
|
|
136
130
|
self.assertEqual(len(rows), len(objects))
|
|
@@ -142,13 +136,13 @@ class CsvTest(FrontTestCase):
|
|
|
142
136
|
def test_adapter_fields_as_list_with_nested(self):
|
|
143
137
|
@csv.adapter(Fake)
|
|
144
138
|
class Adapter(csv.Adapter):
|
|
145
|
-
fields = [
|
|
139
|
+
fields = ["title", "description", "sub.key"]
|
|
146
140
|
|
|
147
141
|
objects = FakeFactory.build_batch(3)
|
|
148
142
|
adapter = Adapter(objects)
|
|
149
143
|
|
|
150
144
|
header = adapter.header()
|
|
151
|
-
self.assertEqual(header, [
|
|
145
|
+
self.assertEqual(header, ["title", "description", "sub.key"])
|
|
152
146
|
|
|
153
147
|
rows = list(adapter.rows())
|
|
154
148
|
self.assertEqual(len(rows), len(objects))
|
|
@@ -162,17 +156,17 @@ class CsvTest(FrontTestCase):
|
|
|
162
156
|
@csv.adapter(Fake)
|
|
163
157
|
class Adapter(csv.Adapter):
|
|
164
158
|
fields = (
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
(
|
|
168
|
-
(
|
|
159
|
+
"title",
|
|
160
|
+
"description",
|
|
161
|
+
("tags", lambda o: ",".join(o.tags)),
|
|
162
|
+
("alias", "title"),
|
|
169
163
|
)
|
|
170
164
|
|
|
171
165
|
objects = FakeFactory.build_batch(3)
|
|
172
166
|
adapter = Adapter(objects)
|
|
173
167
|
|
|
174
168
|
header = adapter.header()
|
|
175
|
-
self.assertEqual(header, [
|
|
169
|
+
self.assertEqual(header, ["title", "description", "tags", "alias"])
|
|
176
170
|
|
|
177
171
|
rows = list(adapter.rows())
|
|
178
172
|
self.assertEqual(len(rows), len(objects))
|
|
@@ -180,26 +174,22 @@ class CsvTest(FrontTestCase):
|
|
|
180
174
|
self.assertEqual(len(row), len(header))
|
|
181
175
|
self.assertEqual(row[0], obj.title)
|
|
182
176
|
self.assertEqual(row[1], obj.description)
|
|
183
|
-
self.assertEqual(row[2],
|
|
177
|
+
self.assertEqual(row[2], ",".join(obj.tags))
|
|
184
178
|
self.assertEqual(row[3], obj.title)
|
|
185
179
|
|
|
186
180
|
def test_adapter_fields_with_method(self):
|
|
187
181
|
@csv.adapter(Fake)
|
|
188
182
|
class Adapter(csv.Adapter):
|
|
189
|
-
fields = (
|
|
190
|
-
'title',
|
|
191
|
-
'description',
|
|
192
|
-
'tags'
|
|
193
|
-
)
|
|
183
|
+
fields = ("title", "description", "tags")
|
|
194
184
|
|
|
195
185
|
def field_tags(self, obj):
|
|
196
|
-
return
|
|
186
|
+
return ",".join(obj.tags)
|
|
197
187
|
|
|
198
188
|
objects = FakeFactory.build_batch(3)
|
|
199
189
|
adapter = Adapter(objects)
|
|
200
190
|
|
|
201
191
|
header = adapter.header()
|
|
202
|
-
self.assertEqual(header, [
|
|
192
|
+
self.assertEqual(header, ["title", "description", "tags"])
|
|
203
193
|
|
|
204
194
|
rows = list(adapter.rows())
|
|
205
195
|
self.assertEqual(len(rows), len(objects))
|
|
@@ -207,27 +197,25 @@ class CsvTest(FrontTestCase):
|
|
|
207
197
|
self.assertEqual(len(row), len(header))
|
|
208
198
|
self.assertEqual(row[0], obj.title)
|
|
209
199
|
self.assertEqual(row[1], obj.description)
|
|
210
|
-
self.assertEqual(row[2],
|
|
200
|
+
self.assertEqual(row[2], ",".join(obj.tags))
|
|
211
201
|
|
|
212
202
|
def test_adapter_fields_with_dyanmic_fields(self):
|
|
213
203
|
@csv.adapter(Fake)
|
|
214
204
|
class Adapter(csv.Adapter):
|
|
215
|
-
fields = (
|
|
216
|
-
'title',
|
|
217
|
-
)
|
|
205
|
+
fields = ("title",)
|
|
218
206
|
|
|
219
207
|
def dynamic_fields(self):
|
|
220
208
|
return (
|
|
221
|
-
|
|
222
|
-
(
|
|
223
|
-
(
|
|
209
|
+
"description",
|
|
210
|
+
("alias", "title"),
|
|
211
|
+
("tags", lambda o: ",".join(o.tags)),
|
|
224
212
|
)
|
|
225
213
|
|
|
226
214
|
objects = FakeFactory.build_batch(3)
|
|
227
215
|
adapter = Adapter(objects)
|
|
228
216
|
|
|
229
217
|
header = adapter.header()
|
|
230
|
-
self.assertEqual(header, [
|
|
218
|
+
self.assertEqual(header, ["title", "description", "alias", "tags"])
|
|
231
219
|
|
|
232
220
|
rows = list(adapter.rows())
|
|
233
221
|
self.assertEqual(len(rows), len(objects))
|
|
@@ -236,15 +224,14 @@ class CsvTest(FrontTestCase):
|
|
|
236
224
|
self.assertEqual(row[0], obj.title)
|
|
237
225
|
self.assertEqual(row[1], obj.description)
|
|
238
226
|
self.assertEqual(row[2], obj.title)
|
|
239
|
-
self.assertEqual(row[3],
|
|
227
|
+
self.assertEqual(row[3], ",".join(obj.tags))
|
|
240
228
|
|
|
241
229
|
def test_metric_fields(self):
|
|
242
230
|
expected = {
|
|
243
|
-
|
|
244
|
-
|
|
231
|
+
"metric.fake-metric-int": 5,
|
|
232
|
+
"metric.fake-metric-float": 0.5,
|
|
245
233
|
}
|
|
246
|
-
fake = FakeFactory(
|
|
247
|
-
metrics={'fake-metric-int': 5, 'fake-metric-float': 0.5})
|
|
234
|
+
fake = FakeFactory(metrics={"fake-metric-int": 5, "fake-metric-float": 0.5})
|
|
248
235
|
|
|
249
236
|
fields = csv.metric_fields(Fake)
|
|
250
237
|
self.assertEqual(len(fields), len(expected))
|
|
@@ -255,13 +242,13 @@ class CsvTest(FrontTestCase):
|
|
|
255
242
|
def test_unicode(self):
|
|
256
243
|
@csv.adapter(Fake)
|
|
257
244
|
class Adapter(csv.Adapter):
|
|
258
|
-
fields = [
|
|
245
|
+
fields = ["title", "description"]
|
|
259
246
|
|
|
260
|
-
objects = FakeFactory.build_batch(3, description=
|
|
247
|
+
objects = FakeFactory.build_batch(3, description="é\xe9")
|
|
261
248
|
adapter = Adapter(objects)
|
|
262
249
|
|
|
263
250
|
header = adapter.header()
|
|
264
|
-
self.assertEqual(header, [
|
|
251
|
+
self.assertEqual(header, ["title", "description"])
|
|
265
252
|
|
|
266
253
|
rows = list(adapter.rows())
|
|
267
254
|
self.assertEqual(len(rows), len(objects))
|
|
@@ -279,18 +266,18 @@ class CsvTest(FrontTestCase):
|
|
|
279
266
|
def assert_csv(self, endpoint, objects):
|
|
280
267
|
@csv.adapter(Fake)
|
|
281
268
|
class Adapter(csv.Adapter):
|
|
282
|
-
fields = [
|
|
269
|
+
fields = ["title", "description"]
|
|
283
270
|
|
|
284
271
|
response = self.get(url_for(endpoint))
|
|
285
272
|
|
|
286
273
|
self.assert200(response)
|
|
287
|
-
self.assertEqual(response.mimetype,
|
|
288
|
-
self.assertEqual(response.charset,
|
|
274
|
+
self.assertEqual(response.mimetype, "text/csv")
|
|
275
|
+
self.assertEqual(response.charset, "utf-8")
|
|
289
276
|
|
|
290
|
-
csvfile = StringIO(response.data.decode(
|
|
277
|
+
csvfile = StringIO(response.data.decode("utf8"))
|
|
291
278
|
reader = csv.get_reader(csvfile)
|
|
292
279
|
header = next(reader)
|
|
293
|
-
self.assertEqual(header, [
|
|
280
|
+
self.assertEqual(header, ["title", "description"])
|
|
294
281
|
|
|
295
282
|
rows = list(reader)
|
|
296
283
|
self.assertEqual(len(rows), len(objects))
|
|
@@ -302,55 +289,53 @@ class CsvTest(FrontTestCase):
|
|
|
302
289
|
return response
|
|
303
290
|
|
|
304
291
|
def assert_filename(self, response, basename):
|
|
305
|
-
header = response.headers[
|
|
292
|
+
header = response.headers["Content-Disposition"]
|
|
306
293
|
m = RE_ATTACHMENT.match(header)
|
|
307
|
-
self.assertIsNotNone(
|
|
308
|
-
|
|
309
|
-
'Content-Disposition header should specify a filename attachment')
|
|
310
|
-
filename = m.group('filename')
|
|
294
|
+
self.assertIsNotNone(m, "Content-Disposition header should specify a filename attachment")
|
|
295
|
+
filename = m.group("filename")
|
|
311
296
|
m = RE_FILENAME.match(filename)
|
|
312
|
-
self.assertIsNotNone(m,
|
|
313
|
-
self.assertEqual(m.group(
|
|
297
|
+
self.assertIsNotNone(m, "filename should have the right pattern")
|
|
298
|
+
self.assertEqual(m.group("basename"), basename)
|
|
314
299
|
|
|
315
300
|
def test_stream_from_adapter(self):
|
|
316
|
-
response = self.assert_stream_csv(
|
|
317
|
-
self.assert_filename(response,
|
|
301
|
+
response = self.assert_stream_csv("testcsv.from_adapter")
|
|
302
|
+
self.assert_filename(response, "export")
|
|
318
303
|
|
|
319
304
|
def test_stream_from_queryset(self):
|
|
320
|
-
response = self.assert_stream_csv(
|
|
321
|
-
self.assert_filename(response,
|
|
305
|
+
response = self.assert_stream_csv("testcsv.from_queryset")
|
|
306
|
+
self.assert_filename(response, "export")
|
|
322
307
|
|
|
323
308
|
def test_stream_from_list(self):
|
|
324
|
-
response = self.assert_stream_csv(
|
|
325
|
-
self.assert_filename(response,
|
|
309
|
+
response = self.assert_stream_csv("testcsv.from_list")
|
|
310
|
+
self.assert_filename(response, "export")
|
|
326
311
|
|
|
327
312
|
def test_stream_with_basename(self):
|
|
328
|
-
response = self.assert_stream_csv(
|
|
329
|
-
self.assert_filename(response,
|
|
313
|
+
response = self.assert_stream_csv("testcsv.with_basename")
|
|
314
|
+
self.assert_filename(response, "test")
|
|
330
315
|
|
|
331
316
|
def test_empty_stream_from_adapter(self):
|
|
332
|
-
response = self.assert_empty_stream_csv(
|
|
333
|
-
self.assert_filename(response,
|
|
317
|
+
response = self.assert_empty_stream_csv("testcsv.from_adapter")
|
|
318
|
+
self.assert_filename(response, "export")
|
|
334
319
|
|
|
335
320
|
def test_empty_stream_from_queryset(self):
|
|
336
|
-
response = self.assert_empty_stream_csv(
|
|
337
|
-
self.assert_filename(response,
|
|
321
|
+
response = self.assert_empty_stream_csv("testcsv.from_queryset")
|
|
322
|
+
self.assert_filename(response, "export")
|
|
338
323
|
|
|
339
324
|
def test_stream_nested_from_adapter(self):
|
|
340
325
|
fake = FakeFactory.build()
|
|
341
326
|
for i in range(3):
|
|
342
327
|
fake.nested.append(NestedFake(key=faker.word(), value=i))
|
|
343
328
|
fake.save()
|
|
344
|
-
response = self.get(url_for(
|
|
329
|
+
response = self.get(url_for("testcsv.from_nested"))
|
|
345
330
|
|
|
346
331
|
self.assert200(response)
|
|
347
|
-
self.assertEqual(response.mimetype,
|
|
348
|
-
self.assertEqual(response.charset,
|
|
332
|
+
self.assertEqual(response.mimetype, "text/csv")
|
|
333
|
+
self.assertEqual(response.charset, "utf-8")
|
|
349
334
|
|
|
350
|
-
csvfile = StringIO(response.data.decode(
|
|
335
|
+
csvfile = StringIO(response.data.decode("utf8"))
|
|
351
336
|
reader = csv.get_reader(csvfile)
|
|
352
337
|
header = next(reader)
|
|
353
|
-
self.assertEqual(header, [
|
|
338
|
+
self.assertEqual(header, ["title", "description", "key", "alias"])
|
|
354
339
|
|
|
355
340
|
rows = list(reader)
|
|
356
341
|
self.assertEqual(len(rows), len(fake.nested))
|
|
@@ -362,17 +347,17 @@ class CsvTest(FrontTestCase):
|
|
|
362
347
|
self.assertEqual(row[3], str(obj.value))
|
|
363
348
|
|
|
364
349
|
def test_stream_unicode(self):
|
|
365
|
-
fake = FakeFactory(title=
|
|
366
|
-
response = self.get(url_for(
|
|
350
|
+
fake = FakeFactory(title="é\xe9")
|
|
351
|
+
response = self.get(url_for("testcsv.from_adapter"))
|
|
367
352
|
|
|
368
353
|
self.assert200(response)
|
|
369
|
-
self.assertEqual(response.mimetype,
|
|
370
|
-
self.assertEqual(response.charset,
|
|
354
|
+
self.assertEqual(response.mimetype, "text/csv")
|
|
355
|
+
self.assertEqual(response.charset, "utf-8")
|
|
371
356
|
|
|
372
|
-
csvfile = StringIO(response.data.decode(
|
|
357
|
+
csvfile = StringIO(response.data.decode("utf8"))
|
|
373
358
|
reader = csv.get_reader(csvfile)
|
|
374
359
|
header = next(reader)
|
|
375
|
-
self.assertEqual(header, [
|
|
360
|
+
self.assertEqual(header, ["title", "description"])
|
|
376
361
|
|
|
377
362
|
row = next(reader)
|
|
378
363
|
self.assertEqual(len(row), len(header))
|
|
@@ -1,93 +1,93 @@
|
|
|
1
1
|
import pytest
|
|
2
|
-
|
|
3
2
|
from flask import Blueprint, render_template_string, url_for
|
|
3
|
+
|
|
4
4
|
from udata.frontend import template_hook
|
|
5
5
|
from udata.tests.helpers import assert200
|
|
6
6
|
|
|
7
|
-
bp = Blueprint(
|
|
7
|
+
bp = Blueprint("hooks_tests", __name__, url_prefix="/hooks_tests")
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
@template_hook
|
|
11
11
|
def single(ctx):
|
|
12
|
-
return
|
|
12
|
+
return "single"
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
@template_hook
|
|
16
16
|
def hello(ctx, name):
|
|
17
|
-
return
|
|
17
|
+
return "Hello {}".format(name)
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
@template_hook
|
|
21
21
|
def kwargs(ctx, **kwargs):
|
|
22
|
-
return
|
|
22
|
+
return ", ".join(sorted("{0}={1}".format(k, v) for k, v in kwargs.items()))
|
|
23
23
|
|
|
24
24
|
|
|
25
|
-
@template_hook(
|
|
25
|
+
@template_hook("multiple")
|
|
26
26
|
def first(ctx):
|
|
27
|
-
return
|
|
27
|
+
return "first"
|
|
28
28
|
|
|
29
29
|
|
|
30
|
-
@template_hook(
|
|
30
|
+
@template_hook("multiple")
|
|
31
31
|
def second(ctx):
|
|
32
|
-
return
|
|
32
|
+
return "second"
|
|
33
33
|
|
|
34
34
|
|
|
35
|
-
@template_hook(
|
|
35
|
+
@template_hook("conditionnal", when=lambda ctx: True)
|
|
36
36
|
def true(ctx):
|
|
37
|
-
return
|
|
37
|
+
return "true"
|
|
38
38
|
|
|
39
39
|
|
|
40
|
-
@template_hook(
|
|
40
|
+
@template_hook("conditionnal", when=lambda ctx: False)
|
|
41
41
|
def false(ctx):
|
|
42
|
-
return
|
|
42
|
+
return "false"
|
|
43
43
|
|
|
44
44
|
|
|
45
|
-
@bp.route(
|
|
45
|
+
@bp.route("/empty/render")
|
|
46
46
|
def render_empty():
|
|
47
47
|
return render_template_string('{{ hook("empty") }}')
|
|
48
48
|
|
|
49
49
|
|
|
50
|
-
@bp.route(
|
|
50
|
+
@bp.route("/empty/iter")
|
|
51
51
|
def iter_empty():
|
|
52
52
|
return render_template_string('{% for w in hook("empty") %}<{{ w }}>{% endfor %}')
|
|
53
53
|
|
|
54
54
|
|
|
55
|
-
@bp.route(
|
|
55
|
+
@bp.route("/hello")
|
|
56
56
|
def render_hello():
|
|
57
57
|
return render_template_string('{{ hook("hello", "world") }}')
|
|
58
58
|
|
|
59
59
|
|
|
60
|
-
@bp.route(
|
|
60
|
+
@bp.route("/kwargs")
|
|
61
61
|
def render_kwargs():
|
|
62
62
|
return render_template_string('{{ hook("kwargs", key="value", other=42) }}')
|
|
63
63
|
|
|
64
64
|
|
|
65
|
-
@bp.route(
|
|
65
|
+
@bp.route("/single/render")
|
|
66
66
|
def render_single():
|
|
67
67
|
return render_template_string('{{ hook("single") }}')
|
|
68
68
|
|
|
69
69
|
|
|
70
|
-
@bp.route(
|
|
70
|
+
@bp.route("/single/iter")
|
|
71
71
|
def iter_single():
|
|
72
72
|
return render_template_string('{% for w in hook("single") %}<{{ w }}>{% endfor %}')
|
|
73
73
|
|
|
74
74
|
|
|
75
|
-
@bp.route(
|
|
75
|
+
@bp.route("/multiple/render")
|
|
76
76
|
def render_multiple():
|
|
77
77
|
return render_template_string('{{ hook("multiple") }}')
|
|
78
78
|
|
|
79
79
|
|
|
80
|
-
@bp.route(
|
|
80
|
+
@bp.route("/multiple/iter")
|
|
81
81
|
def iter_multiple():
|
|
82
82
|
return render_template_string('{% for w in hook("multiple") %}<{{ w }}>{% endfor %}')
|
|
83
83
|
|
|
84
84
|
|
|
85
|
-
@bp.route(
|
|
85
|
+
@bp.route("/conditionnal/render")
|
|
86
86
|
def render_conditionnal():
|
|
87
87
|
return render_template_string('{{ hook("conditionnal") }}')
|
|
88
88
|
|
|
89
89
|
|
|
90
|
-
@bp.route(
|
|
90
|
+
@bp.route("/conditionnal/iter")
|
|
91
91
|
def iter_conditionnal():
|
|
92
92
|
return render_template_string('{% for w in hook("conditionnal") %}<{{ w }}>{% endfor %}')
|
|
93
93
|
|
|
@@ -101,51 +101,51 @@ def app(app):
|
|
|
101
101
|
@pytest.mark.frontend
|
|
102
102
|
class HooksTest:
|
|
103
103
|
def test_empty_template_hook(self, client):
|
|
104
|
-
response = client.get(url_for(
|
|
104
|
+
response = client.get(url_for("hooks_tests.render_empty"))
|
|
105
105
|
assert200(response)
|
|
106
|
-
assert b
|
|
106
|
+
assert b"" == response.data
|
|
107
107
|
|
|
108
108
|
def test_iter_empty_template_hook(self, client):
|
|
109
|
-
response = client.get(url_for(
|
|
109
|
+
response = client.get(url_for("hooks_tests.iter_empty"))
|
|
110
110
|
assert200(response)
|
|
111
|
-
assert b
|
|
111
|
+
assert b"" == response.data
|
|
112
112
|
|
|
113
113
|
def test_single_template_hook(self, client):
|
|
114
|
-
response = client.get(url_for(
|
|
114
|
+
response = client.get(url_for("hooks_tests.render_single"))
|
|
115
115
|
assert200(response)
|
|
116
|
-
assert b
|
|
116
|
+
assert b"single" == response.data
|
|
117
117
|
|
|
118
118
|
def test_iter_single_template_hook(self, client):
|
|
119
|
-
response = client.get(url_for(
|
|
119
|
+
response = client.get(url_for("hooks_tests.iter_single"))
|
|
120
120
|
assert200(response)
|
|
121
|
-
assert b
|
|
121
|
+
assert b"<single>" == response.data
|
|
122
122
|
|
|
123
123
|
def test_multiple_template_hooks(self, client):
|
|
124
|
-
response = client.get(url_for(
|
|
124
|
+
response = client.get(url_for("hooks_tests.render_multiple"))
|
|
125
125
|
assert200(response)
|
|
126
|
-
assert b
|
|
126
|
+
assert b"firstsecond" == response.data
|
|
127
127
|
|
|
128
128
|
def test_iter_multiple_template_hooks(self, client):
|
|
129
|
-
response = client.get(url_for(
|
|
129
|
+
response = client.get(url_for("hooks_tests.iter_multiple"))
|
|
130
130
|
assert200(response)
|
|
131
|
-
assert b
|
|
131
|
+
assert b"<first><second>" == response.data
|
|
132
132
|
|
|
133
133
|
def test_conditionnal_template_hooks(self, client):
|
|
134
|
-
response = client.get(url_for(
|
|
134
|
+
response = client.get(url_for("hooks_tests.render_conditionnal"))
|
|
135
135
|
assert200(response)
|
|
136
|
-
assert b
|
|
136
|
+
assert b"true" == response.data
|
|
137
137
|
|
|
138
138
|
def test_iter_conditionnal_template_hooks(self, client):
|
|
139
|
-
response = client.get(url_for(
|
|
139
|
+
response = client.get(url_for("hooks_tests.iter_conditionnal"))
|
|
140
140
|
assert200(response)
|
|
141
|
-
assert b
|
|
141
|
+
assert b"<true>" == response.data
|
|
142
142
|
|
|
143
143
|
def test_arguments(self, client):
|
|
144
|
-
response = client.get(url_for(
|
|
144
|
+
response = client.get(url_for("hooks_tests.render_hello"))
|
|
145
145
|
assert200(response)
|
|
146
|
-
assert b
|
|
146
|
+
assert b"Hello world" == response.data
|
|
147
147
|
|
|
148
148
|
def test_kwargs(self, client):
|
|
149
|
-
response = client.get(url_for(
|
|
149
|
+
response = client.get(url_for("hooks_tests.render_kwargs"))
|
|
150
150
|
assert200(response)
|
|
151
|
-
assert b
|
|
151
|
+
assert b"key=value, other=42" == response.data
|