udata 12.0.2.dev15__py3-none-any.whl → 13.0.1.dev21__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of udata might be problematic. Click here for more details.
- udata/api/__init__.py +1 -0
- udata/api_fields.py +10 -4
- udata/app.py +11 -10
- udata/auth/__init__.py +9 -10
- udata/auth/mails.py +137 -45
- udata/auth/views.py +5 -12
- udata/commands/__init__.py +2 -3
- udata/commands/info.py +1 -3
- udata/commands/tests/test_fixtures.py +6 -3
- udata/core/access_type/api.py +18 -0
- udata/core/access_type/constants.py +98 -0
- udata/core/access_type/models.py +44 -0
- udata/core/activity/models.py +1 -1
- udata/core/badges/models.py +1 -1
- udata/core/badges/tasks.py +35 -1
- udata/core/badges/tests/test_commands.py +2 -4
- udata/core/badges/tests/test_model.py +2 -2
- udata/core/badges/tests/test_tasks.py +55 -0
- udata/core/constants.py +1 -0
- udata/core/contact_point/models.py +8 -0
- udata/core/dataservices/api.py +3 -3
- udata/core/dataservices/apiv2.py +3 -1
- udata/core/dataservices/constants.py +0 -29
- udata/core/dataservices/models.py +44 -44
- udata/core/dataservices/rdf.py +2 -1
- udata/core/dataservices/search.py +5 -9
- udata/core/dataservices/tasks.py +33 -0
- udata/core/dataset/api_fields.py +11 -0
- udata/core/dataset/apiv2.py +11 -0
- udata/core/dataset/constants.py +0 -1
- udata/core/dataset/forms.py +29 -0
- udata/core/dataset/models.py +16 -4
- udata/core/dataset/rdf.py +2 -1
- udata/core/dataset/search.py +2 -2
- udata/core/dataset/tasks.py +86 -8
- udata/core/discussions/mails.py +63 -0
- udata/core/discussions/tasks.py +4 -18
- udata/core/metrics/__init__.py +0 -6
- udata/core/organization/api.py +3 -1
- udata/core/organization/mails.py +144 -0
- udata/core/organization/models.py +2 -1
- udata/core/organization/search.py +1 -1
- udata/core/organization/tasks.py +21 -49
- udata/core/pages/tests/test_api.py +0 -2
- udata/core/reuse/api.py +27 -1
- udata/core/reuse/mails.py +21 -0
- udata/core/reuse/models.py +10 -1
- udata/core/reuse/search.py +1 -1
- udata/core/reuse/tasks.py +2 -3
- udata/core/site/models.py +2 -6
- udata/core/spatial/tests/test_api.py +17 -20
- udata/core/spatial/tests/test_models.py +3 -3
- udata/core/user/mails.py +54 -0
- udata/core/user/models.py +2 -3
- udata/core/user/tasks.py +8 -23
- udata/core/user/tests/test_user_model.py +2 -6
- udata/entrypoints.py +0 -5
- udata/features/identicon/tests/test_backends.py +3 -13
- udata/forms/fields.py +3 -3
- udata/forms/widgets.py +2 -2
- udata/frontend/__init__.py +3 -32
- udata/harvest/actions.py +4 -9
- udata/harvest/api.py +5 -14
- udata/harvest/backends/__init__.py +20 -11
- udata/harvest/backends/base.py +2 -2
- udata/harvest/backends/ckan/harvesters.py +2 -1
- udata/harvest/backends/dcat.py +3 -0
- udata/harvest/backends/maaf.py +1 -0
- udata/harvest/commands.py +6 -4
- udata/harvest/forms.py +9 -6
- udata/harvest/tasks.py +3 -5
- udata/harvest/tests/ckan/test_ckan_backend.py +300 -337
- udata/harvest/tests/ckan/test_ckan_backend_errors.py +94 -99
- udata/harvest/tests/ckan/test_ckan_backend_filters.py +128 -122
- udata/harvest/tests/ckan/test_dkan_backend.py +39 -51
- udata/harvest/tests/dcat/datara--5a26b0f6-0ccf-46ad-ac58-734054b91977.rdf.xml +255 -0
- udata/harvest/tests/dcat/datara--f40c3860-7236-4b30-a141-23b8ae33f7b2.rdf.xml +289 -0
- udata/harvest/tests/factories.py +1 -1
- udata/harvest/tests/test_actions.py +11 -9
- udata/harvest/tests/test_api.py +4 -5
- udata/harvest/tests/test_base_backend.py +5 -4
- udata/harvest/tests/test_dcat_backend.py +50 -19
- udata/harvest/tests/test_models.py +2 -4
- udata/harvest/tests/test_notifications.py +2 -4
- udata/harvest/tests/test_tasks.py +2 -3
- udata/mail.py +90 -53
- udata/migrations/2025-01-05-dataservices-fields-changes.py +8 -14
- udata/migrations/2025-10-21-remove-ckan-harvest-modified-at.py +28 -0
- udata/migrations/2025-10-29-harvesters-sources-integrity.py +27 -0
- udata/mongo/taglist_field.py +3 -3
- udata/rdf.py +32 -15
- udata/sentry.py +3 -4
- udata/settings.py +7 -2
- udata/tags.py +5 -5
- udata/tasks.py +3 -3
- udata/templates/mail/message.html +65 -0
- udata/templates/mail/message.txt +16 -0
- udata/tests/__init__.py +40 -58
- udata/tests/api/__init__.py +87 -2
- udata/tests/api/test_activities_api.py +17 -23
- udata/tests/api/test_auth_api.py +2 -4
- udata/tests/api/test_contact_points.py +48 -54
- udata/tests/api/test_dataservices_api.py +57 -37
- udata/tests/api/test_datasets_api.py +146 -49
- udata/tests/api/test_me_api.py +4 -6
- udata/tests/api/test_organizations_api.py +19 -38
- udata/tests/api/test_reports_api.py +0 -4
- udata/tests/api/test_reuses_api.py +92 -19
- udata/tests/api/test_security_api.py +124 -0
- udata/tests/api/test_swagger.py +2 -3
- udata/tests/api/test_tags_api.py +6 -7
- udata/tests/api/test_transfer_api.py +0 -2
- udata/tests/api/test_user_api.py +8 -10
- udata/tests/apiv2/test_datasets.py +0 -4
- udata/tests/apiv2/test_me_api.py +0 -2
- udata/tests/apiv2/test_organizations.py +0 -2
- udata/tests/apiv2/test_swagger.py +2 -3
- udata/tests/apiv2/test_topics.py +0 -2
- udata/tests/cli/test_cli_base.py +14 -12
- udata/tests/cli/test_db_cli.py +51 -54
- udata/tests/contact_point/test_contact_point_models.py +2 -2
- udata/tests/dataservice/test_csv_adapter.py +2 -5
- udata/tests/dataservice/test_dataservice_rdf.py +8 -6
- udata/tests/dataservice/test_dataservice_tasks.py +36 -38
- udata/tests/dataset/test_csv_adapter.py +2 -5
- udata/tests/dataset/test_dataset_actions.py +2 -4
- udata/tests/dataset/test_dataset_commands.py +2 -4
- udata/tests/dataset/test_dataset_events.py +3 -3
- udata/tests/dataset/test_dataset_model.py +6 -7
- udata/tests/dataset/test_dataset_rdf.py +201 -12
- udata/tests/dataset/test_dataset_recommendations.py +2 -2
- udata/tests/dataset/test_dataset_tasks.py +66 -68
- udata/tests/dataset/test_resource_preview.py +39 -48
- udata/tests/dataset/test_transport_tasks.py +2 -2
- udata/tests/features/territories/__init__.py +0 -6
- udata/tests/features/territories/test_territories_api.py +25 -24
- udata/tests/forms/test_current_user_field.py +2 -2
- udata/tests/forms/test_dict_field.py +2 -4
- udata/tests/forms/test_extras_fields.py +2 -3
- udata/tests/forms/test_image_field.py +2 -2
- udata/tests/forms/test_model_field.py +2 -4
- udata/tests/forms/test_publish_as_field.py +2 -4
- udata/tests/forms/test_user_forms.py +26 -29
- udata/tests/frontend/test_auth.py +2 -3
- udata/tests/frontend/test_csv.py +5 -6
- udata/tests/frontend/test_error_handlers.py +2 -3
- udata/tests/frontend/test_hooks.py +5 -7
- udata/tests/frontend/test_markdown.py +3 -4
- udata/tests/helpers.py +2 -7
- udata/tests/metrics/test_metrics.py +52 -48
- udata/tests/metrics/test_tasks.py +154 -150
- udata/tests/organization/test_csv_adapter.py +2 -5
- udata/tests/organization/test_notifications.py +2 -4
- udata/tests/organization/test_organization_model.py +3 -4
- udata/tests/organization/test_organization_rdf.py +2 -8
- udata/tests/plugin.py +6 -110
- udata/tests/reuse/test_reuse_model.py +3 -4
- udata/tests/site/test_site_api.py +0 -2
- udata/tests/site/test_site_csv_exports.py +0 -2
- udata/tests/site/test_site_metrics.py +2 -4
- udata/tests/site/test_site_model.py +2 -2
- udata/tests/site/test_site_rdf.py +4 -7
- udata/tests/test_activity.py +3 -3
- udata/tests/test_api_fields.py +6 -9
- udata/tests/test_cors.py +0 -2
- udata/tests/test_dcat_commands.py +2 -3
- udata/tests/test_discussions.py +2 -7
- udata/tests/test_mail.py +150 -114
- udata/tests/test_migrations.py +413 -419
- udata/tests/test_model.py +10 -11
- udata/tests/test_notifications.py +2 -3
- udata/tests/test_owned.py +3 -3
- udata/tests/test_rdf.py +19 -15
- udata/tests/test_routing.py +5 -5
- udata/tests/test_storages.py +6 -5
- udata/tests/test_tags.py +2 -4
- udata/tests/test_topics.py +2 -4
- udata/tests/test_transfer.py +4 -5
- udata/tests/topic/test_topic_tasks.py +25 -27
- udata/tests/user/test_user_rdf.py +2 -8
- udata/tests/user/test_user_tasks.py +3 -5
- udata/tests/workers/test_jobs_commands.py +2 -2
- udata/tests/workers/test_tasks_routing.py +27 -27
- udata/translations/ar/LC_MESSAGES/udata.mo +0 -0
- udata/translations/ar/LC_MESSAGES/udata.po +369 -435
- udata/translations/de/LC_MESSAGES/udata.mo +0 -0
- udata/translations/de/LC_MESSAGES/udata.po +371 -437
- udata/translations/es/LC_MESSAGES/udata.mo +0 -0
- udata/translations/es/LC_MESSAGES/udata.po +369 -435
- udata/translations/fr/LC_MESSAGES/udata.mo +0 -0
- udata/translations/fr/LC_MESSAGES/udata.po +381 -447
- udata/translations/it/LC_MESSAGES/udata.mo +0 -0
- udata/translations/it/LC_MESSAGES/udata.po +371 -437
- udata/translations/pt/LC_MESSAGES/udata.mo +0 -0
- udata/translations/pt/LC_MESSAGES/udata.po +371 -437
- udata/translations/sr/LC_MESSAGES/udata.mo +0 -0
- udata/translations/sr/LC_MESSAGES/udata.po +372 -438
- udata/translations/udata.pot +379 -440
- udata/utils.py +14 -2
- {udata-12.0.2.dev15.dist-info → udata-13.0.1.dev21.dist-info}/METADATA +1 -2
- {udata-12.0.2.dev15.dist-info → udata-13.0.1.dev21.dist-info}/RECORD +205 -242
- udata/templates/mail/account_deleted.html +0 -5
- udata/templates/mail/account_deleted.txt +0 -6
- udata/templates/mail/account_inactivity.html +0 -40
- udata/templates/mail/account_inactivity.txt +0 -31
- udata/templates/mail/badge_added_association.html +0 -33
- udata/templates/mail/badge_added_association.txt +0 -11
- udata/templates/mail/badge_added_certified.html +0 -33
- udata/templates/mail/badge_added_certified.txt +0 -11
- udata/templates/mail/badge_added_company.html +0 -33
- udata/templates/mail/badge_added_company.txt +0 -11
- udata/templates/mail/badge_added_local_authority.html +0 -33
- udata/templates/mail/badge_added_local_authority.txt +0 -11
- udata/templates/mail/badge_added_public_service.html +0 -33
- udata/templates/mail/badge_added_public_service.txt +0 -11
- udata/templates/mail/discussion_closed.html +0 -47
- udata/templates/mail/discussion_closed.txt +0 -16
- udata/templates/mail/inactive_account_deleted.html +0 -5
- udata/templates/mail/inactive_account_deleted.txt +0 -6
- udata/templates/mail/membership_refused.html +0 -20
- udata/templates/mail/membership_refused.txt +0 -11
- udata/templates/mail/membership_request.html +0 -46
- udata/templates/mail/membership_request.txt +0 -12
- udata/templates/mail/new_discussion.html +0 -44
- udata/templates/mail/new_discussion.txt +0 -15
- udata/templates/mail/new_discussion_comment.html +0 -45
- udata/templates/mail/new_discussion_comment.txt +0 -16
- udata/templates/mail/new_member.html +0 -27
- udata/templates/mail/new_member.txt +0 -11
- udata/templates/mail/new_reuse.html +0 -37
- udata/templates/mail/new_reuse.txt +0 -9
- udata/templates/mail/test.html +0 -6
- udata/templates/mail/test.txt +0 -6
- udata/templates/mail/user_mail_card.html +0 -26
- udata/templates/security/email/base.html +0 -105
- udata/templates/security/email/base.txt +0 -6
- udata/templates/security/email/button.html +0 -3
- udata/templates/security/email/change_notice.html +0 -22
- udata/templates/security/email/change_notice.txt +0 -8
- udata/templates/security/email/confirmation_instructions.html +0 -20
- udata/templates/security/email/confirmation_instructions.txt +0 -7
- udata/templates/security/email/login_instructions.html +0 -19
- udata/templates/security/email/login_instructions.txt +0 -7
- udata/templates/security/email/reset_instructions.html +0 -24
- udata/templates/security/email/reset_instructions.txt +0 -9
- udata/templates/security/email/reset_notice.html +0 -11
- udata/templates/security/email/reset_notice.txt +0 -4
- udata/templates/security/email/welcome.html +0 -24
- udata/templates/security/email/welcome.txt +0 -9
- udata/templates/security/email/welcome_existing.html +0 -32
- udata/templates/security/email/welcome_existing.txt +0 -14
- udata/terms.md +0 -6
- udata/tests/frontend/__init__.py +0 -23
- udata/tests/metrics/conftest.py +0 -15
- {udata-12.0.2.dev15.dist-info → udata-13.0.1.dev21.dist-info}/WHEEL +0 -0
- {udata-12.0.2.dev15.dist-info → udata-13.0.1.dev21.dist-info}/entry_points.txt +0 -0
- {udata-12.0.2.dev15.dist-info → udata-13.0.1.dev21.dist-info}/licenses/LICENSE +0 -0
- {udata-12.0.2.dev15.dist-info → udata-13.0.1.dev21.dist-info}/top_level.txt +0 -0
|
@@ -7,13 +7,14 @@ from werkzeug.test import TestResponse
|
|
|
7
7
|
|
|
8
8
|
import udata.core.organization.constants as org_constants
|
|
9
9
|
from udata.core.badges.factories import badge_factory
|
|
10
|
+
from udata.core.dataservices.factories import DataserviceFactory
|
|
10
11
|
from udata.core.dataset.factories import DatasetFactory
|
|
11
12
|
from udata.core.organization.factories import OrganizationFactory
|
|
12
13
|
from udata.core.reuse.constants import REUSE_TOPICS, REUSE_TYPES
|
|
13
14
|
from udata.core.reuse.factories import ReuseFactory
|
|
14
15
|
from udata.core.user.factories import AdminFactory, UserFactory
|
|
15
16
|
from udata.models import Follow, Member, Reuse
|
|
16
|
-
from udata.tests.api import APITestCase
|
|
17
|
+
from udata.tests.api import APITestCase, PytestOnlyAPITestCase
|
|
17
18
|
from udata.tests.helpers import (
|
|
18
19
|
assert200,
|
|
19
20
|
assert201,
|
|
@@ -24,19 +25,13 @@ from udata.tests.helpers import (
|
|
|
24
25
|
)
|
|
25
26
|
from udata.utils import faker
|
|
26
27
|
|
|
27
|
-
pytestmark = [
|
|
28
|
-
pytest.mark.usefixtures("clean_db"),
|
|
29
|
-
]
|
|
30
|
-
|
|
31
28
|
|
|
32
29
|
def reuse_in_response(response: TestResponse, reuse: Reuse) -> bool:
|
|
33
30
|
only_reuse = [r for r in response.json["data"] if r["id"] == str(reuse.id)]
|
|
34
31
|
return len(only_reuse) > 0
|
|
35
32
|
|
|
36
33
|
|
|
37
|
-
class ReuseAPITest:
|
|
38
|
-
modules = []
|
|
39
|
-
|
|
34
|
+
class ReuseAPITest(PytestOnlyAPITestCase):
|
|
40
35
|
def test_reuse_api_list(self, api):
|
|
41
36
|
"""It should fetch a reuse list from the API"""
|
|
42
37
|
reuses = ReuseFactory.create_batch(3, visible=True)
|
|
@@ -381,6 +376,22 @@ class ReuseAPITest:
|
|
|
381
376
|
response = api.delete(url_for("api.reuse", reuse=reuse))
|
|
382
377
|
assert410(response)
|
|
383
378
|
|
|
379
|
+
def test_reuse_api_filter_by_dataset(self, api):
|
|
380
|
+
user = api.login()
|
|
381
|
+
dataset = DatasetFactory()
|
|
382
|
+
other_dataset = DatasetFactory()
|
|
383
|
+
ReuseFactory(owner=user, datasets=[dataset])
|
|
384
|
+
|
|
385
|
+
response = api.get(url_for("api.reuses", dataset=dataset.id))
|
|
386
|
+
assert200(response)
|
|
387
|
+
assert response.json["total"] == 1
|
|
388
|
+
assert len(response.json["data"][0]["datasets"]) == 1
|
|
389
|
+
assert response.json["data"][0]["datasets"][0]["title"] == dataset.title
|
|
390
|
+
|
|
391
|
+
response = api.get(url_for("api.reuses", dataset=other_dataset.id))
|
|
392
|
+
assert200(response)
|
|
393
|
+
assert response.json["total"] == 0
|
|
394
|
+
|
|
384
395
|
def test_reuse_api_add_dataset(self, api):
|
|
385
396
|
"""It should add a dataset to a reuse from the API"""
|
|
386
397
|
user = api.login()
|
|
@@ -431,6 +442,72 @@ class ReuseAPITest:
|
|
|
431
442
|
reuse.reload()
|
|
432
443
|
assert len(reuse.datasets) == 0
|
|
433
444
|
|
|
445
|
+
def test_reuse_api_filter_by_dataservice(self, api):
|
|
446
|
+
user = api.login()
|
|
447
|
+
dataservice = DataserviceFactory()
|
|
448
|
+
other_dataservice = DataserviceFactory()
|
|
449
|
+
ReuseFactory(owner=user, dataservices=[dataservice])
|
|
450
|
+
|
|
451
|
+
response = api.get(url_for("api.reuses", dataservice=dataservice.id))
|
|
452
|
+
assert200(response)
|
|
453
|
+
assert response.json["total"] == 1
|
|
454
|
+
assert len(response.json["data"][0]["dataservices"]) == 1
|
|
455
|
+
assert response.json["data"][0]["dataservices"][0]["title"] == dataservice.title
|
|
456
|
+
|
|
457
|
+
response = api.get(url_for("api.reuses", dataservice=other_dataservice.id))
|
|
458
|
+
assert200(response)
|
|
459
|
+
assert response.json["total"] == 0
|
|
460
|
+
|
|
461
|
+
def test_reuse_api_add_dataservice(self, api):
|
|
462
|
+
"""It should add a dataset to a reuse from the API"""
|
|
463
|
+
user = api.login()
|
|
464
|
+
reuse = ReuseFactory(owner=user)
|
|
465
|
+
|
|
466
|
+
dataservice = DataserviceFactory()
|
|
467
|
+
data = {"id": dataservice.id, "class": "Dataservice"}
|
|
468
|
+
url = url_for("api.reuse_add_dataservice", reuse=reuse)
|
|
469
|
+
response = api.post(url, data)
|
|
470
|
+
assert201(response)
|
|
471
|
+
reuse.reload()
|
|
472
|
+
assert len(reuse.dataservices) == 1
|
|
473
|
+
assert reuse.dataservices[-1] == dataservice
|
|
474
|
+
|
|
475
|
+
dataservice = DataserviceFactory()
|
|
476
|
+
data = {"id": dataservice.id, "class": "dataservice"}
|
|
477
|
+
url = url_for("api.reuse_add_dataservice", reuse=reuse)
|
|
478
|
+
response = api.post(url, data)
|
|
479
|
+
assert201(response)
|
|
480
|
+
reuse.reload()
|
|
481
|
+
assert len(reuse.dataservices) == 2
|
|
482
|
+
assert reuse.dataservices[-1] == dataservice
|
|
483
|
+
|
|
484
|
+
def test_reuse_api_add_dataservice_twice(self, api):
|
|
485
|
+
"""It should not add twice a dataservice to a reuse from the API"""
|
|
486
|
+
user = api.login()
|
|
487
|
+
dataservice = DataserviceFactory()
|
|
488
|
+
reuse = ReuseFactory(owner=user, dataservices=[dataservice])
|
|
489
|
+
|
|
490
|
+
data = {"id": dataservice.id, "class": "Dataservice"}
|
|
491
|
+
url = url_for("api.reuse_add_dataservice", reuse=reuse)
|
|
492
|
+
response = api.post(url, data)
|
|
493
|
+
assert200(response)
|
|
494
|
+
reuse.reload()
|
|
495
|
+
assert len(reuse.dataservices) == 1
|
|
496
|
+
assert reuse.dataservices[-1] == dataservice
|
|
497
|
+
|
|
498
|
+
def test_reuse_api_add_dataservice_not_found(self, api):
|
|
499
|
+
"""It should return 404 when adding an unknown dataservice to a reuse"""
|
|
500
|
+
user = api.login()
|
|
501
|
+
reuse = ReuseFactory(owner=user)
|
|
502
|
+
|
|
503
|
+
data = {"id": "not-found", "class": "Dataservice"}
|
|
504
|
+
url = url_for("api.reuse_add_dataservice", reuse=reuse)
|
|
505
|
+
response = api.post(url, data)
|
|
506
|
+
|
|
507
|
+
assert404(response)
|
|
508
|
+
reuse.reload()
|
|
509
|
+
assert len(reuse.dataservices) == 0
|
|
510
|
+
|
|
434
511
|
def test_reuse_api_feature(self, api):
|
|
435
512
|
"""It should mark the reuse featured on POST"""
|
|
436
513
|
reuse = ReuseFactory(featured=False)
|
|
@@ -523,7 +600,7 @@ class ReuseAPITest:
|
|
|
523
600
|
title="arealtestprefix-4", visible=True, metrics={"followers": 10}
|
|
524
601
|
)
|
|
525
602
|
|
|
526
|
-
response = api.get(url_for("api.suggest_reuses"
|
|
603
|
+
response = api.get(url_for("api.suggest_reuses", q="arealtestpref", size=5))
|
|
527
604
|
assert200(response)
|
|
528
605
|
|
|
529
606
|
assert len(response.json) <= 5
|
|
@@ -542,7 +619,7 @@ class ReuseAPITest:
|
|
|
542
619
|
for i in range(4):
|
|
543
620
|
ReuseFactory(title="testé-{0}".format(i) if i % 2 else faker.word(), visible=True)
|
|
544
621
|
|
|
545
|
-
response = api.get(url_for("api.suggest_reuses"
|
|
622
|
+
response = api.get(url_for("api.suggest_reuses", q="testé", size=5))
|
|
546
623
|
assert200(response)
|
|
547
624
|
|
|
548
625
|
assert len(response.json) <= 5
|
|
@@ -559,14 +636,14 @@ class ReuseAPITest:
|
|
|
559
636
|
"""It should not provide reuse suggestion if no match"""
|
|
560
637
|
ReuseFactory.create_batch(3, visible=True)
|
|
561
638
|
|
|
562
|
-
response = api.get(url_for("api.suggest_reuses"
|
|
639
|
+
response = api.get(url_for("api.suggest_reuses", q="xxxxxx", size=5))
|
|
563
640
|
assert200(response)
|
|
564
641
|
assert len(response.json) == 0
|
|
565
642
|
|
|
566
643
|
def test_suggest_reuses_api_empty(self, api):
|
|
567
644
|
"""It should not provide reuse suggestion if no data"""
|
|
568
645
|
# self.init_search()
|
|
569
|
-
response = api.get(url_for("api.suggest_reuses"
|
|
646
|
+
response = api.get(url_for("api.suggest_reuses", q="xxxxxx", size=5))
|
|
570
647
|
assert200(response)
|
|
571
648
|
assert len(response.json) == 0
|
|
572
649
|
|
|
@@ -630,11 +707,9 @@ class ReusesFeedAPItest(APITestCase):
|
|
|
630
707
|
self.assertEqual(author.href, org.url_for())
|
|
631
708
|
|
|
632
709
|
|
|
633
|
-
class ReuseBadgeAPITest:
|
|
634
|
-
modules = []
|
|
635
|
-
|
|
710
|
+
class ReuseBadgeAPITest(PytestOnlyAPITestCase):
|
|
636
711
|
@pytest.fixture(autouse=True)
|
|
637
|
-
def
|
|
712
|
+
def setup_func(self, api):
|
|
638
713
|
# Register at least two badges
|
|
639
714
|
Reuse.__badges__["test-1"] = "Test 1"
|
|
640
715
|
Reuse.__badges__["test-2"] = "Test 2"
|
|
@@ -695,9 +770,7 @@ class ReuseBadgeAPITest:
|
|
|
695
770
|
assert404(response)
|
|
696
771
|
|
|
697
772
|
|
|
698
|
-
class ReuseReferencesAPITest:
|
|
699
|
-
modules = []
|
|
700
|
-
|
|
773
|
+
class ReuseReferencesAPITest(PytestOnlyAPITestCase):
|
|
701
774
|
def test_reuse_types_list(self, api):
|
|
702
775
|
"""It should fetch the reuse types list from the API"""
|
|
703
776
|
response = api.get(url_for("api.reuse_types"))
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
from datetime import datetime
|
|
2
|
+
|
|
3
|
+
import pytest
|
|
4
|
+
from flask import url_for
|
|
5
|
+
from flask_security.recoverable import generate_reset_password_token
|
|
6
|
+
|
|
7
|
+
from udata.commands.fixtures import UserFactory
|
|
8
|
+
from udata.i18n import lazy_gettext as _
|
|
9
|
+
from udata.tests.api import PytestOnlyAPITestCase
|
|
10
|
+
from udata.tests.helpers import capture_mails
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class SecurityAPITest(PytestOnlyAPITestCase):
|
|
14
|
+
@pytest.mark.options(CAPTCHETAT_BASE_URL=None)
|
|
15
|
+
def test_register(self, api):
|
|
16
|
+
# We cannot test for mail sending since they are sent with Flask
|
|
17
|
+
# directly and not with our system but if the sending is working
|
|
18
|
+
# we test the rendering of the mail.
|
|
19
|
+
|
|
20
|
+
response = api.post(
|
|
21
|
+
url_for("security.register"),
|
|
22
|
+
{
|
|
23
|
+
"first_name": "Jane",
|
|
24
|
+
"last_name": "Doe",
|
|
25
|
+
"accept_conditions": True,
|
|
26
|
+
"email": "jane@example.org",
|
|
27
|
+
"password": "Password123",
|
|
28
|
+
"password_confirm": "Password123",
|
|
29
|
+
"submit": True,
|
|
30
|
+
},
|
|
31
|
+
)
|
|
32
|
+
self.assertStatus(response, 200)
|
|
33
|
+
|
|
34
|
+
@pytest.mark.options(CAPTCHETAT_BASE_URL=None, SECURITY_RETURN_GENERIC_RESPONSES=True)
|
|
35
|
+
def test_register_existing(self, api):
|
|
36
|
+
# We cannot test for mail sending since they are sent with Flask
|
|
37
|
+
# directly and not with our system but if the sending is working
|
|
38
|
+
# we test the rendering of the mail.
|
|
39
|
+
|
|
40
|
+
UserFactory(email="jane@example.org", confirmed_at=datetime.now())
|
|
41
|
+
response = api.post(
|
|
42
|
+
url_for("security.register"),
|
|
43
|
+
{
|
|
44
|
+
"first_name": "Jane",
|
|
45
|
+
"last_name": "Doe",
|
|
46
|
+
"accept_conditions": True,
|
|
47
|
+
"email": "jane@example.org",
|
|
48
|
+
"password": "Password123",
|
|
49
|
+
"password_confirm": "Password123",
|
|
50
|
+
"submit": True,
|
|
51
|
+
},
|
|
52
|
+
)
|
|
53
|
+
self.assertStatus(response, 200)
|
|
54
|
+
|
|
55
|
+
@pytest.mark.options(CAPTCHETAT_BASE_URL=None)
|
|
56
|
+
def test_ask_for_reset(self, api):
|
|
57
|
+
# We cannot test for mail sending since they are sent with Flask
|
|
58
|
+
# directly and not with our system but if the sending is working
|
|
59
|
+
# we test the rendering of the mail.
|
|
60
|
+
|
|
61
|
+
UserFactory(email="jane@example.org", confirmed_at=datetime.now())
|
|
62
|
+
|
|
63
|
+
response = api.post(
|
|
64
|
+
url_for("security.forgot_password"), {"email": "jane@example.org", "submit": True}
|
|
65
|
+
)
|
|
66
|
+
self.assertStatus(response, 200)
|
|
67
|
+
|
|
68
|
+
@pytest.mark.options(CAPTCHETAT_BASE_URL=None)
|
|
69
|
+
def test_change_notice_mail(self, api):
|
|
70
|
+
# We cannot test for mail sending since they are sent with Flask
|
|
71
|
+
# directly and not with our system but if the sending is working
|
|
72
|
+
# we test the rendering of the mail.
|
|
73
|
+
|
|
74
|
+
user = UserFactory(
|
|
75
|
+
email="jane@example.org", password="password", confirmed_at=datetime.now()
|
|
76
|
+
)
|
|
77
|
+
self.login(user)
|
|
78
|
+
|
|
79
|
+
response = api.post(
|
|
80
|
+
url_for("security.change_password"),
|
|
81
|
+
{
|
|
82
|
+
"password": "password",
|
|
83
|
+
"new_password": "New_password123",
|
|
84
|
+
"new_password_confirm": "New_password123",
|
|
85
|
+
"submit": True,
|
|
86
|
+
},
|
|
87
|
+
)
|
|
88
|
+
self.assertStatus(response, 200)
|
|
89
|
+
|
|
90
|
+
@pytest.mark.options(CAPTCHETAT_BASE_URL=None)
|
|
91
|
+
def test_change_email_confirmation(self, api):
|
|
92
|
+
user = UserFactory(email="jane@example.org", confirmed_at=datetime.now())
|
|
93
|
+
self.login(user)
|
|
94
|
+
|
|
95
|
+
with capture_mails() as mails:
|
|
96
|
+
response = api.post(
|
|
97
|
+
url_for("security.change_email"),
|
|
98
|
+
{
|
|
99
|
+
"new_email": "jane2@example.org",
|
|
100
|
+
"new_email_confirm": "jane2@example.org",
|
|
101
|
+
"submit": True,
|
|
102
|
+
},
|
|
103
|
+
)
|
|
104
|
+
self.assertStatus(response, 200)
|
|
105
|
+
|
|
106
|
+
assert len(mails) == 1
|
|
107
|
+
assert len(mails[0].recipients) == 1
|
|
108
|
+
assert mails[0].recipients[0] == "jane2@example.org"
|
|
109
|
+
assert mails[0].subject == _("Confirm your email address")
|
|
110
|
+
|
|
111
|
+
@pytest.mark.options(CAPTCHETAT_BASE_URL=None, SECURITY_RETURN_GENERIC_RESPONSES=True)
|
|
112
|
+
def test_reset_password(self, api):
|
|
113
|
+
user = UserFactory(email="jane@example.org", confirmed_at=datetime.now())
|
|
114
|
+
token = generate_reset_password_token(user)
|
|
115
|
+
|
|
116
|
+
response = api.post(
|
|
117
|
+
url_for("security.reset_password", token=token),
|
|
118
|
+
{
|
|
119
|
+
"password": "Password123",
|
|
120
|
+
"password_confirm": "Password123",
|
|
121
|
+
"submit": True,
|
|
122
|
+
},
|
|
123
|
+
)
|
|
124
|
+
self.assertStatus(response, 200)
|
udata/tests/api/test_swagger.py
CHANGED
|
@@ -3,12 +3,11 @@ import json
|
|
|
3
3
|
from flask import url_for
|
|
4
4
|
from flask_restx import schemas
|
|
5
5
|
|
|
6
|
+
from udata.tests.api import PytestOnlyAPITestCase
|
|
6
7
|
from udata.tests.helpers import assert200
|
|
7
8
|
|
|
8
9
|
|
|
9
|
-
class SwaggerBlueprintTest:
|
|
10
|
-
modules = []
|
|
11
|
-
|
|
10
|
+
class SwaggerBlueprintTest(PytestOnlyAPITestCase):
|
|
12
11
|
def test_swagger_resource_type(self, api):
|
|
13
12
|
response = api.get(url_for("api.specs"))
|
|
14
13
|
assert200(response)
|
udata/tests/api/test_tags_api.py
CHANGED
|
@@ -1,15 +1,14 @@
|
|
|
1
|
-
import pytest
|
|
2
1
|
from flask import url_for
|
|
3
2
|
|
|
4
3
|
from udata.core.dataset.factories import DatasetFactory
|
|
5
4
|
from udata.core.reuse.factories import ReuseFactory
|
|
6
5
|
from udata.core.tags.tasks import count_tags
|
|
6
|
+
from udata.tests.api import PytestOnlyAPITestCase
|
|
7
7
|
from udata.tests.helpers import assert200
|
|
8
8
|
from udata.utils import faker
|
|
9
9
|
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
class TagsAPITest:
|
|
11
|
+
class TagsAPITest(PytestOnlyAPITestCase):
|
|
13
12
|
def test_suggest_tags_api(self, api):
|
|
14
13
|
"""It should suggest tags"""
|
|
15
14
|
for i in range(3):
|
|
@@ -19,7 +18,7 @@ class TagsAPITest:
|
|
|
19
18
|
|
|
20
19
|
count_tags()
|
|
21
20
|
|
|
22
|
-
response = api.get(url_for("api.suggest_tags"
|
|
21
|
+
response = api.get(url_for("api.suggest_tags", q="tes", size=5))
|
|
23
22
|
assert200(response)
|
|
24
23
|
|
|
25
24
|
assert len(response.json) <= 5
|
|
@@ -39,7 +38,7 @@ class TagsAPITest:
|
|
|
39
38
|
|
|
40
39
|
count_tags()
|
|
41
40
|
|
|
42
|
-
response = api.get(url_for("api.suggest_tags"
|
|
41
|
+
response = api.get(url_for("api.suggest_tags", q="testé", size=5))
|
|
43
42
|
assert200(response)
|
|
44
43
|
|
|
45
44
|
assert len(response.json) <= 5
|
|
@@ -59,12 +58,12 @@ class TagsAPITest:
|
|
|
59
58
|
|
|
60
59
|
count_tags()
|
|
61
60
|
|
|
62
|
-
response = api.get(url_for("api.suggest_tags"
|
|
61
|
+
response = api.get(url_for("api.suggest_tags", q="bbbb", size=5))
|
|
63
62
|
assert200(response)
|
|
64
63
|
assert len(response.json) == 0
|
|
65
64
|
|
|
66
65
|
def test_suggest_tags_api_empty(self, api):
|
|
67
66
|
"""It should not provide tag suggestion if no data"""
|
|
68
|
-
response = api.get(url_for("api.suggest_tags"
|
|
67
|
+
response = api.get(url_for("api.suggest_tags", q="bbbb", size=5))
|
|
69
68
|
assert200(response)
|
|
70
69
|
assert len(response.json) == 0
|
udata/tests/api/test_user_api.py
CHANGED
|
@@ -11,8 +11,6 @@ from . import APITestCase
|
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
class UserAPITest(APITestCase):
|
|
14
|
-
modules = []
|
|
15
|
-
|
|
16
14
|
def test_follow_user(self):
|
|
17
15
|
"""It should follow an user on POST"""
|
|
18
16
|
user = self.login()
|
|
@@ -65,7 +63,7 @@ class UserAPITest(APITestCase):
|
|
|
65
63
|
for i in range(4):
|
|
66
64
|
UserFactory(first_name="first-name-test-{0}".format(i) if i % 2 else faker.word())
|
|
67
65
|
|
|
68
|
-
response = self.get(url_for("api.suggest_users"
|
|
66
|
+
response = self.get(url_for("api.suggest_users", q="first-name-test", size=5))
|
|
69
67
|
self.assert200(response)
|
|
70
68
|
|
|
71
69
|
self.assertLessEqual(len(response.json), 5)
|
|
@@ -84,7 +82,7 @@ class UserAPITest(APITestCase):
|
|
|
84
82
|
for i in range(4):
|
|
85
83
|
UserFactory(last_name="last-name-test-{0}".format(i) if i % 2 else faker.word())
|
|
86
84
|
|
|
87
|
-
response = self.get(url_for("api.suggest_users"
|
|
85
|
+
response = self.get(url_for("api.suggest_users", q="last-name-test", size=5))
|
|
88
86
|
self.assert200(response)
|
|
89
87
|
|
|
90
88
|
self.assertLessEqual(len(response.json), 5)
|
|
@@ -102,7 +100,7 @@ class UserAPITest(APITestCase):
|
|
|
102
100
|
for i in range(4):
|
|
103
101
|
UserFactory(last_name="last-name-testé-{0}".format(i) if i % 2 else faker.word())
|
|
104
102
|
|
|
105
|
-
response = self.get(url_for("api.suggest_users"
|
|
103
|
+
response = self.get(url_for("api.suggest_users", q="last-name-testé", size=5))
|
|
106
104
|
self.assert200(response)
|
|
107
105
|
|
|
108
106
|
self.assertLessEqual(len(response.json), 5)
|
|
@@ -119,13 +117,13 @@ class UserAPITest(APITestCase):
|
|
|
119
117
|
"""It should not provide user suggestion if no match"""
|
|
120
118
|
UserFactory.create_batch(3)
|
|
121
119
|
|
|
122
|
-
response = self.get(url_for("api.suggest_users"
|
|
120
|
+
response = self.get(url_for("api.suggest_users", q="xxxxxx", size=5))
|
|
123
121
|
self.assert200(response)
|
|
124
122
|
self.assertEqual(len(response.json), 0)
|
|
125
123
|
|
|
126
124
|
def test_suggest_users_api_empty(self):
|
|
127
125
|
"""It should not provide user suggestion if no data"""
|
|
128
|
-
response = self.get(url_for("api.suggest_users"
|
|
126
|
+
response = self.get(url_for("api.suggest_users", q="xxxxxx", size=5))
|
|
129
127
|
self.assert200(response)
|
|
130
128
|
self.assertEqual(len(response.json), 0)
|
|
131
129
|
|
|
@@ -133,7 +131,7 @@ class UserAPITest(APITestCase):
|
|
|
133
131
|
"""It should suggest users without deduplicating homonyms"""
|
|
134
132
|
UserFactory.create_batch(2, first_name="test", last_name="homonym")
|
|
135
133
|
|
|
136
|
-
response = self.get(url_for("api.suggest_users"
|
|
134
|
+
response = self.get(url_for("api.suggest_users", q="homonym", size=5))
|
|
137
135
|
self.assert200(response)
|
|
138
136
|
|
|
139
137
|
self.assertEqual(len(response.json), 2)
|
|
@@ -144,11 +142,11 @@ class UserAPITest(APITestCase):
|
|
|
144
142
|
|
|
145
143
|
def test_suggest_users_api_size_validation(self):
|
|
146
144
|
"""It should validate that the size parameter is between 1 and 20."""
|
|
147
|
-
response = self.get(url_for("api.suggest_users"
|
|
145
|
+
response = self.get(url_for("api.suggest_users", q="foobar", size=0))
|
|
148
146
|
self.assert400(response)
|
|
149
147
|
self.assertIn("between 1 and 20", response.json["errors"]["size"])
|
|
150
148
|
|
|
151
|
-
response = self.get(url_for("api.suggest_users"
|
|
149
|
+
response = self.get(url_for("api.suggest_users", q="foobar", size=21))
|
|
152
150
|
|
|
153
151
|
self.assert400(response)
|
|
154
152
|
self.assertIn("between 1 and 20", response.json["errors"]["size"])
|
|
@@ -367,8 +367,6 @@ class DatasetResourceAPIV2Test(APITestCase):
|
|
|
367
367
|
|
|
368
368
|
|
|
369
369
|
class DatasetExtrasAPITest(APITestCase):
|
|
370
|
-
modules = None
|
|
371
|
-
|
|
372
370
|
def setUp(self):
|
|
373
371
|
self.login()
|
|
374
372
|
self.dataset = DatasetFactory(owner=self.user)
|
|
@@ -503,8 +501,6 @@ class DatasetExtrasAPITest(APITestCase):
|
|
|
503
501
|
|
|
504
502
|
|
|
505
503
|
class DatasetResourceExtrasAPITest(APITestCase):
|
|
506
|
-
modules = None
|
|
507
|
-
|
|
508
504
|
def setUp(self):
|
|
509
505
|
self.login()
|
|
510
506
|
self.dataset = DatasetFactory(owner=self.user)
|
udata/tests/apiv2/test_me_api.py
CHANGED
|
@@ -3,12 +3,11 @@ import json
|
|
|
3
3
|
from flask import url_for
|
|
4
4
|
from flask_restx import schemas
|
|
5
5
|
|
|
6
|
+
from udata.tests.api import PytestOnlyAPITestCase
|
|
6
7
|
from udata.tests.helpers import assert200
|
|
7
8
|
|
|
8
9
|
|
|
9
|
-
class SwaggerBlueprintTest:
|
|
10
|
-
modules = []
|
|
11
|
-
|
|
10
|
+
class SwaggerBlueprintTest(PytestOnlyAPITestCase):
|
|
12
11
|
def test_swagger_resource_type(self, api):
|
|
13
12
|
response = api.get(url_for("apiv2.specs"))
|
|
14
13
|
assert200(response)
|
udata/tests/apiv2/test_topics.py
CHANGED
udata/tests/cli/test_cli_base.py
CHANGED
|
@@ -1,16 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
"""Should display help without errors"""
|
|
3
|
-
cli()
|
|
4
|
-
cli("-?")
|
|
5
|
-
cli("-h")
|
|
6
|
-
cli("--help")
|
|
1
|
+
from udata.tests import PytestOnlyTestCase
|
|
7
2
|
|
|
8
3
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
4
|
+
class CliBaseTest(PytestOnlyTestCase):
|
|
5
|
+
def test_cli_help(self, cli):
|
|
6
|
+
"""Should display help without errors"""
|
|
7
|
+
cli()
|
|
8
|
+
cli("-?")
|
|
9
|
+
cli("-h")
|
|
10
|
+
cli("--help")
|
|
12
11
|
|
|
12
|
+
def test_cli_log_and_printing(self, cli):
|
|
13
|
+
"""Should properly log and print"""
|
|
14
|
+
cli("test log")
|
|
13
15
|
|
|
14
|
-
def test_cli_version(cli):
|
|
15
|
-
|
|
16
|
-
|
|
16
|
+
def test_cli_version(self, cli):
|
|
17
|
+
"""Should display version without errors"""
|
|
18
|
+
cli("--version")
|