udata 14.5.1.dev9__py3-none-any.whl → 14.6.1.dev5__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.

Files changed (32) hide show
  1. udata/api_fields.py +27 -4
  2. udata/core/badges/tests/test_tasks.py +0 -2
  3. udata/core/dataservices/apiv2.py +1 -1
  4. udata/core/dataset/models.py +15 -3
  5. udata/core/dataset/rdf.py +10 -14
  6. udata/core/organization/apiv2.py +1 -1
  7. udata/core/organization/models.py +25 -5
  8. udata/core/post/models.py +2 -0
  9. udata/core/post/tests/test_api.py +5 -1
  10. udata/core/reuse/apiv2.py +1 -1
  11. udata/core/user/models.py +21 -6
  12. udata/features/notifications/models.py +4 -1
  13. udata/features/transfer/models.py +16 -0
  14. udata/features/transfer/notifications.py +74 -0
  15. udata/harvest/backends/ckan/harvesters.py +10 -2
  16. udata/migrations/2021-08-17-harvest-integrity.py +23 -16
  17. udata/migrations/2025-12-16-create-transfer-request-notifications.py +66 -0
  18. udata/tasks.py +1 -0
  19. udata/tests/apiv2/test_dataservices.py +14 -0
  20. udata/tests/apiv2/test_organizations.py +9 -0
  21. udata/tests/apiv2/test_reuses.py +11 -0
  22. udata/tests/dataset/test_dataset_rdf.py +49 -0
  23. udata/tests/search/test_search_integration.py +37 -0
  24. udata/tests/test_transfer.py +104 -1
  25. udata/utils.py +23 -0
  26. {udata-14.5.1.dev9.dist-info → udata-14.6.1.dev5.dist-info}/METADATA +2 -2
  27. {udata-14.5.1.dev9.dist-info → udata-14.6.1.dev5.dist-info}/RECORD +31 -29
  28. udata/tests/apiv2/test_search.py +0 -30
  29. {udata-14.5.1.dev9.dist-info → udata-14.6.1.dev5.dist-info}/WHEEL +0 -0
  30. {udata-14.5.1.dev9.dist-info → udata-14.6.1.dev5.dist-info}/entry_points.txt +0 -0
  31. {udata-14.5.1.dev9.dist-info → udata-14.6.1.dev5.dist-info}/licenses/LICENSE +0 -0
  32. {udata-14.5.1.dev9.dist-info → udata-14.6.1.dev5.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,66 @@
1
+ """
2
+ Create TransferRequestNotification for all pending transfer requests
3
+ """
4
+
5
+ import logging
6
+
7
+ import click
8
+
9
+ from udata.features.notifications.models import Notification
10
+ from udata.features.transfer.models import Transfer
11
+ from udata.features.transfer.notifications import TransferRequestNotificationDetails
12
+
13
+ log = logging.getLogger(__name__)
14
+
15
+
16
+ def migrate(db):
17
+ log.info("Processing pending transfer requests...")
18
+
19
+ created_count = 0
20
+
21
+ # Get all pending transfers
22
+ transfers = Transfer.objects(status="pending")
23
+
24
+ with click.progressbar(transfers, length=transfers.count()) as transfer_list:
25
+ for transfer in transfer_list:
26
+ # Get the recipient (could be a user or an organization)
27
+ recipient = transfer.recipient
28
+
29
+ # For organizations, we need to find admins who should receive notifications
30
+ if recipient._cls == "Organization":
31
+ # Get all admin users for this organization
32
+ recipient_users = [
33
+ member.user for member in recipient.members if member.role == "admin"
34
+ ]
35
+ else:
36
+ # For users, just use the recipient directly
37
+ recipient_users = [recipient]
38
+
39
+ # Create a notification for each recipient user
40
+ for recipient_user in recipient_users:
41
+ try:
42
+ # Check if notification already exists
43
+ existing = Notification.objects(
44
+ user=recipient_user,
45
+ details__transfer_recipient=recipient,
46
+ details__transfer_owner=transfer.owner,
47
+ details__transfer_subject=transfer.subject,
48
+ ).first()
49
+ if not existing:
50
+ notification = Notification(user=recipient_user)
51
+ notification.details = TransferRequestNotificationDetails(
52
+ transfer_owner=transfer.owner,
53
+ transfer_recipient=recipient,
54
+ transfer_subject=transfer.subject,
55
+ )
56
+ # Set the created_at to match the transfer creation date
57
+ notification.created_at = transfer.created
58
+ notification.save()
59
+ created_count += 1
60
+ except Exception as e:
61
+ log.error(
62
+ f"Error creating notification for user {recipient_user.id} "
63
+ f"and transfer {transfer.id}: {e}"
64
+ )
65
+
66
+ log.info(f"Created {created_count} TransferRequestNotifications")
udata/tasks.py CHANGED
@@ -161,6 +161,7 @@ def init_app(app):
161
161
  import udata.core.metrics.tasks # noqa
162
162
  import udata.core.tags.tasks # noqa
163
163
  import udata.core.activity.tasks # noqa
164
+ import udata.core.dataservices.tasks # noqa
164
165
  import udata.core.dataset.tasks # noqa
165
166
  import udata.core.dataset.transport # noqa
166
167
  import udata.core.dataset.recommendations # noqa
@@ -0,0 +1,14 @@
1
+ from udata.core.dataservices.factories import DataserviceFactory
2
+ from udata.tests.api import APITestCase
3
+
4
+
5
+ class DataserviceSearchAPIV2Test(APITestCase):
6
+ def test_dataservice_search_with_model_query_param(self):
7
+ """Searching dataservices with 'model' as query param should not crash.
8
+
9
+ Regression test for: TypeError: query() got multiple values for argument 'model'
10
+ """
11
+ DataserviceFactory.create_batch(3)
12
+
13
+ response = self.get("/api/2/dataservices/search/?model=malicious")
14
+ self.assert200(response)
@@ -4,6 +4,15 @@ from udata.core.organization.factories import Member, OrganizationFactory
4
4
  from udata.tests.api import APITestCase
5
5
 
6
6
 
7
+ class OrganizationSearchAPIV2Test(APITestCase):
8
+ def test_organization_search_with_model_query_param(self):
9
+ """Searching organizations with 'model' as query param should not crash."""
10
+ OrganizationFactory.create_batch(3)
11
+
12
+ response = self.get("/api/2/organizations/search/?model=malicious")
13
+ self.assert200(response)
14
+
15
+
7
16
  class OrganizationExtrasAPITest(APITestCase):
8
17
  def setUp(self):
9
18
  self.login()
@@ -0,0 +1,11 @@
1
+ from udata.core.reuse.factories import ReuseFactory
2
+ from udata.tests.api import APITestCase
3
+
4
+
5
+ class ReuseSearchAPIV2Test(APITestCase):
6
+ def test_reuse_search_with_model_query_param(self):
7
+ """Searching reuses with 'model' as query param should not crash."""
8
+ ReuseFactory.create_batch(3)
9
+
10
+ response = self.get("/api/2/reuses/search/?model=malicious")
11
+ self.assert200(response)
@@ -518,6 +518,22 @@ class RdfToDatasetTest(PytestOnlyDBTestCase):
518
518
  assert isinstance(dataset, Dataset)
519
519
  assert dataset.harvest.modified_at is None
520
520
 
521
+ def test_unparseable_modified_at(self):
522
+ """Regression test: template strings like {{modified:toISO}} should not crash parsing."""
523
+ node = BNode()
524
+ g = Graph()
525
+
526
+ g.add((node, RDF.type, DCAT.Dataset))
527
+ g.add((node, DCT.identifier, Literal(faker.uuid4())))
528
+ g.add((node, DCT.title, Literal(faker.sentence())))
529
+ g.add((node, DCT.modified, Literal("{{modified:toISO}}")))
530
+
531
+ dataset = dataset_from_rdf(g)
532
+ dataset.validate()
533
+
534
+ assert isinstance(dataset, Dataset)
535
+ assert dataset.harvest.modified_at is None
536
+
521
537
  def test_contact_point_individual_vcard(self):
522
538
  g = Graph()
523
539
  node = URIRef("https://test.org/dataset")
@@ -864,6 +880,39 @@ class RdfToDatasetTest(PytestOnlyDBTestCase):
864
880
  assert resource.harvest.modified_at.date() == modified.date()
865
881
  assert resource.format == "csv"
866
882
 
883
+ def test_resource_future_modified_at(self):
884
+ node = BNode()
885
+ g = Graph()
886
+
887
+ modified = faker.future_datetime()
888
+
889
+ g.add((node, RDF.type, DCAT.Distribution))
890
+ g.add((node, DCT.title, Literal(faker.sentence())))
891
+ g.add((node, DCAT.downloadURL, Literal(faker.uri())))
892
+ g.add((node, DCT.modified, Literal(modified)))
893
+
894
+ resource = resource_from_rdf(g)
895
+ resource.validate()
896
+
897
+ assert isinstance(resource, Resource)
898
+ assert resource.harvest.modified_at is None
899
+
900
+ def test_resource_unparseable_modified_at(self):
901
+ """Regression test: template strings like {{modified:toISO}} should not crash parsing."""
902
+ node = BNode()
903
+ g = Graph()
904
+
905
+ g.add((node, RDF.type, DCAT.Distribution))
906
+ g.add((node, DCT.title, Literal(faker.sentence())))
907
+ g.add((node, DCAT.downloadURL, Literal(faker.uri())))
908
+ g.add((node, DCT.modified, Literal("{{modified:toISO}}")))
909
+
910
+ resource = resource_from_rdf(g)
911
+ resource.validate()
912
+
913
+ assert isinstance(resource, Resource)
914
+ assert resource.harvest.modified_at is None
915
+
867
916
  def test_download_url_over_access_url(self):
868
917
  node = BNode()
869
918
  g = Graph()
@@ -3,6 +3,8 @@ import time
3
3
  import pytest
4
4
 
5
5
  from udata.core.dataset.factories import DatasetFactory
6
+ from udata.core.organization.factories import OrganizationFactory
7
+ from udata.core.reuse.factories import VisibleReuseFactory
6
8
  from udata.tests.api import APITestCase
7
9
  from udata.tests.helpers import requires_search_service
8
10
 
@@ -31,3 +33,38 @@ class SearchIntegrationTest(APITestCase):
31
33
 
32
34
  titles = [d["title"] for d in response.json["data"]]
33
35
  assert "Données spectaculaires sur les transports" in titles
36
+
37
+ def test_reuse_search_with_organization_filter(self):
38
+ """
39
+ Regression test for: 500 Server Error when None values are passed to search service.
40
+
41
+ When searching reuses with only an organization filter, other params should not be
42
+ sent as literal 'None' strings (e.g. ?q=None&tag=None).
43
+ """
44
+ org = OrganizationFactory()
45
+ reuse = VisibleReuseFactory(organization=org)
46
+
47
+ time.sleep(1)
48
+
49
+ response = self.get(f"/api/2/reuses/search/?organization={org.id}")
50
+ self.assert200(response)
51
+ assert response.json["total"] >= 1
52
+ ids = [r["id"] for r in response.json["data"]]
53
+ assert str(reuse.id) in ids
54
+
55
+ def test_organization_search_with_query(self):
56
+ """
57
+ Regression test for: 500 Server Error when None values are passed to search service.
58
+
59
+ When searching organizations, other params should not be sent as literal
60
+ 'None' strings (e.g. ?badge=None).
61
+ """
62
+ org = OrganizationFactory(name="Organisation Unique Test")
63
+
64
+ time.sleep(1)
65
+
66
+ response = self.get("/api/2/organizations/search/?q=unique")
67
+ self.assert200(response)
68
+ assert response.json["total"] >= 1
69
+ ids = [o["id"] for o in response.json["data"]]
70
+ assert str(org.id) in ids
@@ -10,11 +10,13 @@ from udata.core.user.factories import UserFactory
10
10
  from udata.core.user.metrics import (
11
11
  update_owner_metrics, # noqa needed to register signals
12
12
  )
13
+ from udata.features.notifications.models import Notification
13
14
  from udata.features.transfer.actions import accept_transfer, request_transfer
14
15
  from udata.features.transfer.factories import TransferFactory
15
16
  from udata.features.transfer.notifications import transfer_request_notifications
16
17
  from udata.models import Member
17
- from udata.tests.api import PytestOnlyDBTestCase
18
+ from udata.tests.api import DBTestCase, PytestOnlyDBTestCase
19
+ from udata.tests.helpers import assert_equal_dates
18
20
  from udata.utils import faker
19
21
 
20
22
 
@@ -218,3 +220,104 @@ class TransferNotificationsTest(PytestOnlyDBTestCase):
218
220
  transfer = transfers[details["id"]]
219
221
  assert details["subject"]["class"] == "dataset"
220
222
  assert details["subject"]["id"] == transfer.subject.id
223
+
224
+
225
+ class TransferRequestNotificationTest(DBTestCase):
226
+ def test_notification_created_for_user_recipient(self):
227
+ """Notification is created for user recipient when transfer is requested"""
228
+ owner = UserFactory()
229
+ recipient = UserFactory()
230
+ dataset = DatasetFactory(owner=owner)
231
+
232
+ login_user(owner)
233
+ transfer = request_transfer(dataset, recipient, faker.sentence())
234
+
235
+ notifications = Notification.objects.all()
236
+ assert len(notifications) == 1
237
+
238
+ notification = notifications[0]
239
+ assert notification.user == recipient
240
+ assert notification.details.transfer_owner == owner
241
+ assert notification.details.transfer_recipient == recipient
242
+ assert notification.details.transfer_subject == dataset
243
+ assert_equal_dates(notification.created_at, transfer.created)
244
+
245
+ def test_notification_created_for_org_admins_only(self):
246
+ """Notifications are created for all admin users of recipient org, not editors"""
247
+ owner = UserFactory()
248
+ admin1 = UserFactory()
249
+ admin2 = UserFactory()
250
+ editor = UserFactory()
251
+ members = [
252
+ Member(user=editor, role="editor"),
253
+ Member(user=admin1, role="admin"),
254
+ Member(user=admin2, role="admin"),
255
+ ]
256
+ org = OrganizationFactory(members=members)
257
+ dataset = DatasetFactory(owner=owner)
258
+
259
+ login_user(owner)
260
+ transfer = request_transfer(dataset, org, faker.sentence())
261
+
262
+ notifications = Notification.objects.all()
263
+ assert len(notifications) == 2
264
+
265
+ admin_users = [notif.user for notif in notifications]
266
+ self.assertIn(admin1, admin_users)
267
+ self.assertIn(admin2, admin_users)
268
+
269
+ for notification in notifications:
270
+ assert notification.details.transfer_owner == owner
271
+ assert notification.details.transfer_recipient == org
272
+ assert notification.details.transfer_subject == dataset
273
+ assert_equal_dates(notification.created_at, transfer.created)
274
+
275
+ def test_no_duplicate_notifications(self):
276
+ """Duplicate notifications are not created for same transfer"""
277
+ owner = UserFactory()
278
+ recipient = UserFactory()
279
+ dataset = DatasetFactory(owner=owner)
280
+
281
+ login_user(owner)
282
+ request_transfer(dataset, recipient, faker.sentence())
283
+ request_transfer(dataset, recipient, faker.sentence())
284
+
285
+ assert Notification.objects.count() == 1
286
+
287
+ def test_multiple_transfers_create_separate_notifications(self):
288
+ """Multiple transfer requests create separate notifications"""
289
+ owner = UserFactory()
290
+ recipient = UserFactory()
291
+ dataset1 = DatasetFactory(owner=owner)
292
+ dataset2 = DatasetFactory(owner=owner)
293
+
294
+ login_user(owner)
295
+ request_transfer(dataset1, recipient, faker.sentence())
296
+ request_transfer(dataset2, recipient, faker.sentence())
297
+
298
+ notifications = Notification.objects.all()
299
+ assert len(notifications) == 2
300
+
301
+ subjects = [notif.details.transfer_subject for notif in notifications]
302
+ self.assertIn(dataset1, subjects)
303
+ self.assertIn(dataset2, subjects)
304
+
305
+ def test_notification_created_for_org_to_user_transfer(self):
306
+ """Notification is created when transferring from org to user"""
307
+ admin = UserFactory()
308
+ org = OrganizationFactory(members=[Member(user=admin, role="admin")])
309
+ dataset = DatasetFactory(organization=org)
310
+ recipient = UserFactory()
311
+
312
+ login_user(admin)
313
+ transfer = request_transfer(dataset, recipient, faker.sentence())
314
+
315
+ notifications = Notification.objects.all()
316
+ assert len(notifications) == 1
317
+
318
+ notification = notifications[0]
319
+ assert notification.user == recipient
320
+ assert notification.details.transfer_owner == org
321
+ assert notification.details.transfer_recipient == recipient
322
+ assert notification.details.transfer_subject == dataset
323
+ assert_equal_dates(notification.created_at, transfer.created)
udata/utils.py CHANGED
@@ -1,5 +1,6 @@
1
1
  import hashlib
2
2
  import itertools
3
+ import logging
3
4
  import math
4
5
  import re
5
6
  from collections import Counter
@@ -13,6 +14,7 @@ from xml.sax.saxutils import escape
13
14
  import factory
14
15
  from bson import ObjectId
15
16
  from bson.errors import InvalidId
17
+ from dateutil.parser import ParserError
16
18
  from dateutil.parser import parse as parse_dt
17
19
  from dateutil.relativedelta import relativedelta
18
20
  from faker import Faker
@@ -216,6 +218,27 @@ def to_naive_datetime(given_date: Any) -> datetime:
216
218
  return given_date
217
219
 
218
220
 
221
+ log = logging.getLogger(__name__)
222
+
223
+
224
+ def safe_harvest_datetime(value: Any, field: str, refuse_future: bool = False) -> datetime | None:
225
+ """
226
+ Safely parse a date/datetime value from harvested data.
227
+ Returns None and logs a warning if the value cannot be parsed or is in the future.
228
+ """
229
+ if value is None:
230
+ return None
231
+ try:
232
+ parsed = to_naive_datetime(value)
233
+ except ParserError:
234
+ log.warning(f"Unparseable {field} value: '{value}'")
235
+ return None
236
+ if refuse_future and parsed and parsed > datetime.utcnow():
237
+ log.warning(f"Future {field} value: '{value}'")
238
+ return None
239
+ return parsed
240
+
241
+
219
242
  def to_iso(dt: date | datetime) -> str | None:
220
243
  """
221
244
  Format a date or datetime into an ISO-8601 string
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: udata
3
- Version: 14.5.1.dev9
3
+ Version: 14.6.1.dev5
4
4
  Summary: Open data portal
5
5
  Author-email: Opendata Team <opendatateam@data.gouv.fr>
6
6
  Maintainer-email: Opendata Team <opendatateam@data.gouv.fr>
@@ -85,7 +85,7 @@ Requires-Dist: tzdata
85
85
  Requires-Dist: urlextract<2.0.0,>=1.9.0
86
86
  Requires-Dist: urllib3<3.0.0,>=2.0.0
87
87
  Requires-Dist: voluptuous<1.0.0,>=0.15.2
88
- Requires-Dist: werkzeug<3.1.4,>=3.0.0
88
+ Requires-Dist: werkzeug<4.0.0,>=3.0.0
89
89
  Requires-Dist: wtforms[email]<4.0.0,>=3.2.1
90
90
  Requires-Dist: wtforms-json<1.0.0,>=0.3.5
91
91
  Dynamic: license-file
@@ -1,5 +1,5 @@
1
1
  udata/__init__.py,sha256=U0HEYqKCLOY43O1UCVeuAb3b3SSX1pPhsJGpHJmK67k,75
2
- udata/api_fields.py,sha256=audhSLNXFXqEZgOo7bKXCTotxU_9mDB5nM9LUSDp44M,38487
2
+ udata/api_fields.py,sha256=Kdp_dzVgYRBy5e5L40F-itQcEJO2FFupKhsW7MHYzsQ,39523
3
3
  udata/app.py,sha256=E4s0z50dHULPY1ZxxCB1H01Qd-EWupT6fk9zg2L9KUw,8521
4
4
  udata/cors.py,sha256=7An9bsiNZk0PbNqDy8--ZJ0vmq1ubrtcfGB3DWAHBlA,3681
5
5
  udata/errors.py,sha256=E8W7b4PH7c5B85g_nsUMt8fHqMVpDFOZFkO6wMPl6bA,117
@@ -12,10 +12,10 @@ udata/sentry.py,sha256=j_6PSHV1id21KFX1XvpQR-Ur4d24310HgIq7MynEZ2Q,2887
12
12
  udata/settings.py,sha256=tk9VyAxg-umX3QW8hfFRsdA683IHxrEOBV-lJOWScGg,22490
13
13
  udata/sitemap.py,sha256=oRRWoPI7ZsFFnUAOqGT1YuXFFKHBe8EcRnUCNHD7xjM,979
14
14
  udata/tags.py,sha256=8R2gJieQtHgj7ZWIckMCkQu39fqzEUehxlYRfSD6bYQ,631
15
- udata/tasks.py,sha256=1cK9HCtbFFbsOztW_3sr-9LDM3h7vKvSW1GaUnOTUnI,5208
15
+ udata/tasks.py,sha256=nP_FqUrRaNvfVLByekN0sRXYTAE2PADMhY5PLTgmN5s,5257
16
16
  udata/tracking.py,sha256=WOcqA1RlHN8EPFuEc2kNau54mec4-pvi-wUFrMXevzg,345
17
17
  udata/uris.py,sha256=YMIZv6ypIYfYGAeLUJuBt58fbkpJ6fSzdWDKCbAylKA,4391
18
- udata/utils.py,sha256=S8ViJSbQgzT3RYbcCW5JTkTjkI1hhifLinPXVuASvl4,13820
18
+ udata/utils.py,sha256=Uxw3glbyKKqp_BC7c9_zAsTPiOOKxhuFyqxbWjvTG80,14531
19
19
  udata/worker.py,sha256=K-Wafye5-uXP4kQlffRKws2J9YbJ6m6n2QjcVsY8Nsg,118
20
20
  udata/wsgi.py,sha256=MY8en9K9eDluvJYUxTdzqSDoYaDgCVZ69ZcUvxAvgqA,77
21
21
  udata/api/__init__.py,sha256=y-ULl38jINI7RfdZezCZ544nIGiZo9_pgo3Zj4NKA8w,11854
@@ -75,7 +75,7 @@ udata/core/badges/tasks.py,sha256=6ulyDIE6GmR1U9UtQWzGA6joupqRF8GntR6CWFifSzY,13
75
75
  udata/core/badges/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
76
76
  udata/core/badges/tests/test_commands.py,sha256=3MMs6DnltAQUClrd7xdi2dYT0qIfmcxojOFL-I9q5Bg,1295
77
77
  udata/core/badges/tests/test_model.py,sha256=pTmGFPNKMvphFMOCYmVaqxCEBdsVAfUVcG5Bhmn3WzI,5409
78
- udata/core/badges/tests/test_tasks.py,sha256=BhBoO1lciq-mADZxojk4Pqtj0BAZarLraeQbDIxascM,2203
78
+ udata/core/badges/tests/test_tasks.py,sha256=0ScMM0NWY7QAAo8LVZzmp2atatuvNwdnQrqX9zhUJbE,2118
79
79
  udata/core/contact_point/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
80
80
  udata/core/contact_point/api.py,sha256=vZI4Ue8hYi1n2aplQ80q_l50aQ4s1YKJwIABFw3lurg,2772
81
81
  udata/core/contact_point/api_fields.py,sha256=qx_80yeRMS6rKSjQZOSGZk56le0t6l2s9_qJ5us8eZg,1396
@@ -85,7 +85,7 @@ udata/core/contact_point/models.py,sha256=4GKbf0C1r1id35t4eQ3RcZIEfS_9kb6WW4QaXq
85
85
  udata/core/dataservices/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
86
86
  udata/core/dataservices/activities.py,sha256=wcYQCyYpKciCz99VqQqKti72a5Fyhc-AvDZBWdF0KUc,1763
87
87
  udata/core/dataservices/api.py,sha256=u1aiwIwz9ypw8I6XT8gAbpN6M3qJGcVSK2UaFRJT5tg,10263
88
- udata/core/dataservices/apiv2.py,sha256=FWkEfreOuyX7Krr604rQzSGLtBoVZrOR4nBEkYlhVIc,1231
88
+ udata/core/dataservices/apiv2.py,sha256=hHwWp0mJtrFJMdylO2_2vPmvdJwFbJNsG9ufcPWONyE,1250
89
89
  udata/core/dataservices/constants.py,sha256=PlfoLJv1rqRSUHbCe80vGkfTl9B0hUYgCxrop_e5JUY,45
90
90
  udata/core/dataservices/csv.py,sha256=HWI2JrN_Vuw0te9FHlJ6eyqcRcKHOKXuzg45D4Ti6F0,1106
91
91
  udata/core/dataservices/factories.py,sha256=pKVoArNSCIbvGA-cWUc7vr8TmjYsUvOXzzcuUB5JyF4,964
@@ -108,10 +108,10 @@ udata/core/dataset/exceptions.py,sha256=uKiayLSpSzsnLvClObS6hOO0qXEqvURKN7_w8eim
108
108
  udata/core/dataset/factories.py,sha256=tb18axsk8Tx5iUIqWM9IELdt-2Ryp2UN0-iY4fdea4U,9059
109
109
  udata/core/dataset/forms.py,sha256=q345go8G6qN1_YTX1Uhpl7M2kqF_44KA91OnFMcOGYk,8207
110
110
  udata/core/dataset/metrics.py,sha256=s8Xs_rqRXfNWsErkiJTuRMG5o_cU5iSK8mUJFKVSc7w,1204
111
- udata/core/dataset/models.py,sha256=NY1h3aY-OQzp80ZR9LuEzg2aXWTHk0srpsAJd_Np5jI,42089
111
+ udata/core/dataset/models.py,sha256=fmJCuRbqVEJR6EzBQWBiPhrf-F-kQMdSGi6LJ_hw13c,42440
112
112
  udata/core/dataset/permissions.py,sha256=qZCo_wKRwm_hONKdAPhYcb4PqJj7qW4PBqH5WJ0FWB4,2199
113
113
  udata/core/dataset/preview.py,sha256=uFEpK-p5nIAlY8hVOMhd7mtkwFt6C_PQRMNxPvAyoo4,839
114
- udata/core/dataset/rdf.py,sha256=jEpp0wrCvpfpkzlNEr6yroLCChcPo9TCHIfbjoRnYPM,33088
114
+ udata/core/dataset/rdf.py,sha256=wYX1olDd6n9M6QEm76q7nV_RVUuwSUDzz46ujIpWg64,32730
115
115
  udata/core/dataset/recommendations.py,sha256=DlGSLU8D0nW6Ds1rjBav1WxC-0VW5yOCjkO5w-ltFcI,7171
116
116
  udata/core/dataset/search.py,sha256=UEYMPwj4kDkGlGaUmsYECh1c3_BjCt1RDcMLDGrV_dA,6019
117
117
  udata/core/dataset/signals.py,sha256=WN4sV-lJlNsRkhcnhoy0SYJvCoYmK_5QFYZd1u-h4gs,161
@@ -154,7 +154,7 @@ udata/core/organization/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG
154
154
  udata/core/organization/activities.py,sha256=Mw4-R8Q6G745IZnCDgrj7h2ax2crGYRhZtcewSK6_Ok,1213
155
155
  udata/core/organization/api.py,sha256=RGyxe5LRqkyk5HzsXRB9r6z_YhGVqNeKkiaEgMaOvU8,22908
156
156
  udata/core/organization/api_fields.py,sha256=NXZc__i31ntun3Zt4OGt2EdpodbtQvHqzuta-TskNPY,7776
157
- udata/core/organization/apiv2.py,sha256=HVZmfO-Cw9hlMPcHKAC1HnSmPXeWpBz-hqWUDl2Bhs8,2983
157
+ udata/core/organization/apiv2.py,sha256=0zn-16vdCgpLkqWGw9XcVp43mrFLGR5mQEPJ-gkv9vA,3002
158
158
  udata/core/organization/commands.py,sha256=DsRAtFDZvTciYNsUWumQWdn0jnNmKW-PwfIHUUZoBb8,1591
159
159
  udata/core/organization/constants.py,sha256=fncNtA-vFrRM22K1Wo6iYu9DQZjzknYxH6TIYfxM9kA,563
160
160
  udata/core/organization/csv.py,sha256=zdLeB4La-TeOEELg0WI3FryoQWnoAYit_DssInVSHRI,979
@@ -162,7 +162,7 @@ udata/core/organization/factories.py,sha256=g8ubBcz79xbjvpunZ02IDOakFg1KE6cXjNkE
162
162
  udata/core/organization/forms.py,sha256=tscDb1_yOpbTx3ahl8ttA7oDkX9jIyzLc4gOf6WbN3s,3552
163
163
  udata/core/organization/mails.py,sha256=JxVzsJe4hoFbohB5hmWY33BmqMg8Bz-nwYDvnvUzXW8,4944
164
164
  udata/core/organization/metrics.py,sha256=CEhkZLUufDyWi2XyizMoXkuddz7xDJvmdkPTweqfWyI,1144
165
- udata/core/organization/models.py,sha256=6_HT7O5Fa1viiC2rv_bY3B8H3v5F-NoMcmCm1hi37Ag,11338
165
+ udata/core/organization/models.py,sha256=cGuavWXqCaCZgTveGKu7dCOFNYN5mv899w19_0Sez0g,12009
166
166
  udata/core/organization/notifications.py,sha256=bAtb-Of3KCAu30KBg0Y55qHJk9kx82HlMWSCYOfYyHM,3710
167
167
  udata/core/organization/permissions.py,sha256=hcnFuc8RkDesFSnq-ei4LV0ZUpRUf8zXyxRoXT_aLQc,1274
168
168
  udata/core/organization/rdf.py,sha256=KYJXTE5Yxhp3Cb7GZsRT1BY3Bd7rcRfwFSK9dWG2xQ4,1807
@@ -178,10 +178,10 @@ udata/core/post/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
178
178
  udata/core/post/api.py,sha256=H8IKX5x9MqcG36Y60DRxOhC00HKyhwLX5lvvSB2AO5c,4863
179
179
  udata/core/post/constants.py,sha256=W-xjOTv0lorD-RCV0YGtK0cT_RwgYmfrC8Ff6ywH7bM,215
180
180
  udata/core/post/factories.py,sha256=lcFe3zIadG7bc1jsydkOT7GfQX53V0x09Flpclyl6gI,619
181
- udata/core/post/models.py,sha256=BuctB_YvthUZh7gibtnBrPeTd2rAxug3Blvf5i6JIok,3780
181
+ udata/core/post/models.py,sha256=p-p-MopRiNic02fTdLR3ECOFUR_nwS2xliTM9dujo0U,3874
182
182
  udata/core/post/permissions.py,sha256=uofU0TehhOGYyUoRXf3wuy816_D3xwMmaJbDvV336sw,83
183
183
  udata/core/post/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
184
- udata/core/post/tests/test_api.py,sha256=zaKfeBdG_cMdUXJ7-qGQIRyVO1t09h-kiJR2nw83bQk,6183
184
+ udata/core/post/tests/test_api.py,sha256=eJWInJtMw4AHS5OpXTaW8oGLi_DdMrkWaSB3hYNQi8s,6347
185
185
  udata/core/reports/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
186
186
  udata/core/reports/api.py,sha256=qrGi1DdRN4mO4nWcyG9rKMiBlw4C8UnzecJFqNAgF_8,2185
187
187
  udata/core/reports/constants.py,sha256=LRZSX3unyqZeB4yQjK3ws_hGbJcXYk4bu1Rhnhi5DEs,1235
@@ -190,7 +190,7 @@ udata/core/reuse/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,
190
190
  udata/core/reuse/activities.py,sha256=5D7cV-hGZnzHsp8hohZqqgK3RSGQpfAqJ_Wfq_AYfM8,1420
191
191
  udata/core/reuse/api.py,sha256=zRHYVkpceWwXyIKM7eMBz0VZAL0TMSdo7m-CicxbN5w,13779
192
192
  udata/core/reuse/api_fields.py,sha256=ccym6v9Ap68PlHZmIMMtHQFnEyV7Gbxrfdw0b6rj51A,1232
193
- udata/core/reuse/apiv2.py,sha256=ixayPlYkCl67GxqFBHijSigjkzmkXuY-HX7X-_SH-3U,863
193
+ udata/core/reuse/apiv2.py,sha256=EGAGY90rZpuKWi2kq7hBPCO9DIpbm9085ebwQSl42wM,882
194
194
  udata/core/reuse/constants.py,sha256=JgDBrjOKSt9q0auv9rjzbGsch83H-Oi8YXAKeI5hO4o,1215
195
195
  udata/core/reuse/csv.py,sha256=c9t9nyAqjx-QNyeku6RpcC8kSdlQ12wxzXCJHUj6GBY,899
196
196
  udata/core/reuse/factories.py,sha256=GrQqYTIvwQrwkvJrbTr38-2faFW_PC99gn3yOVpgFec,850
@@ -262,7 +262,7 @@ udata/core/user/factories.py,sha256=kkwaojciLzfuAOeRnL1E7XCcGPo8waAal_G2eeuVc0k,
262
262
  udata/core/user/forms.py,sha256=yotqZozH9ViKuNI8SwdKocDEi7NXVs_XUMpdr_bIe5s,966
263
263
  udata/core/user/mails.py,sha256=JPoPdjt38T3QECR7g7dqc5MbWxm1wwCNUYIO1I4VSaI,1945
264
264
  udata/core/user/metrics.py,sha256=J4zgjcAudQAi6NUIb47o2Pfe0xZ_Eu17ta9HjhE-HvE,1274
265
- udata/core/user/models.py,sha256=R0imfkTiNTryiccOZIdNgWIhKRwqDgbUMv9EWFgVe4E,11787
265
+ udata/core/user/models.py,sha256=9WIba-F4rmsIeECiJqu-vtPcGdZ2f4EazpOcUznuAKA,12362
266
266
  udata/core/user/permissions.py,sha256=Wbd8bLqSjqp9RHJ6ffLBj74L-LECcAhWazuw4Hq-2Gk,435
267
267
  udata/core/user/rdf.py,sha256=_tN8KlJHt8mYwJhLKoULhmZ3sapUGmX1Sl5W8uawxeU,718
268
268
  udata/core/user/tasks.py,sha256=iaL997_aYTvHSXekHWWHuYb6a1WNQkc48dtfOdE_4SI,2924
@@ -276,14 +276,14 @@ udata/features/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
276
276
  udata/features/notifications/__init__.py,sha256=R4-dHlQxCsLNWXhV05UnPiVuIpKEpV9KBboWnrdNSOo,352
277
277
  udata/features/notifications/actions.py,sha256=i8KvFbsC_JJnPOXSitfdNIdK6ABy8G88E5iwLiGYOyw,759
278
278
  udata/features/notifications/api.py,sha256=mdexblDEqhfQkcTfTT1ZO7dguDunXsopYF5mLuh3IZ0,665
279
- udata/features/notifications/models.py,sha256=0ldEsx3nm_-gJdnhYIKhZJzeux7aaVRLfHlrgwkWu9M,1825
279
+ udata/features/notifications/models.py,sha256=s92gODW0sIULQ4TMdJjMWGnlYDpPJ8YRRZ-vMPYXgaI,1967
280
280
  udata/features/notifications/tasks.py,sha256=dLXiQmElW9cmFAKLzZZgG4aruyRJsMPG7Dsy-U3H0f0,720
281
281
  udata/features/transfer/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
282
282
  udata/features/transfer/actions.py,sha256=u27rJU3E3ZCPYlIMzVesrR1jvIbJIqaJ7EuasXiG8lg,1811
283
283
  udata/features/transfer/api.py,sha256=64lJWb7hFusaGF3bCtJ17-VxhBymzyb7x886vkNProY,6715
284
284
  udata/features/transfer/factories.py,sha256=2dAvRaemGieLn5aVEXQ6cmIGD2dTX5I0Ql2RrT77PfU,208
285
- udata/features/transfer/models.py,sha256=sFmdbEHL7eUxYe2XdtjZ2zhrUWOW_ryP_5T_8N1qUEA,958
286
- udata/features/transfer/notifications.py,sha256=jeH5buqTuWcokgXfEj-EZ7C3YCrtw-NikfrH2bqFyHM,1121
285
+ udata/features/transfer/models.py,sha256=b84x6CKzGKOfgA1VKzPaV1LvZ5GtT3kgEFqYpszRZlg,1420
286
+ udata/features/transfer/notifications.py,sha256=ynRizwI-JvZvFc68uaAzre65s-6-Zj_SnQCq79BbP4Q,3604
287
287
  udata/features/transfer/permissions.py,sha256=0Iwt_I3S3QACpq4Ba6Ovb8RUBuozj2pbXDtFFp9jdLI,953
288
288
  udata/flask_mongoengine/__init__.py,sha256=Ijqs6lu009OSWgUFdw1AdihjbbLL7-BekwZojXg92bU,599
289
289
  udata/flask_mongoengine/connection.py,sha256=b4dPVa8X_xbCFJ8ngt-RWLZtjNCHyZQSw-0fhRL6ySA,5191
@@ -318,7 +318,7 @@ udata/harvest/backends/dcat.py,sha256=FwFJ0SHhKkyrUUfILYn3iZ79dQJqGUF3BhW7Qrxb5f
318
318
  udata/harvest/backends/maaf.py,sha256=SN_831VeWphR63EC9v0n94bRH-9B5htTE70HSsVfzyc,8373
319
319
  udata/harvest/backends/maaf.xsd,sha256=vEyG8Vqw7Yn_acjRdXjqUJgxOj4pv8bibep-FX-f3BQ,18322
320
320
  udata/harvest/backends/ckan/__init__.py,sha256=JE7Qa7kX7Yd8OvmJnAO_NupZe0tqYyhhkgJ-iGNxX64,35
321
- udata/harvest/backends/ckan/harvesters.py,sha256=Bi4teYM1_Pw0HacRPObWFZimAxSz9CVdS9nGyb__Tnc,11035
321
+ udata/harvest/backends/ckan/harvesters.py,sha256=q_tkdpPE9lCTSe1l1KK-sFsujCVqUZfoCflZV5Hw5bE,11356
322
322
  udata/harvest/backends/ckan/schemas/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
323
323
  udata/harvest/backends/ckan/schemas/ckan.py,sha256=59VQoIxPBb5vOHFzzMtdnPcxHL4qNOTkPYa4cqn-7xQ,2353
324
324
  udata/harvest/backends/ckan/schemas/dkan.py,sha256=RyQGPEaKqnunIrr9yApcz7WEfgye0IT1bV85wa2E8Lc,2774
@@ -371,7 +371,7 @@ udata/migrations/2021-05-27-fix-default-schema-name.py,sha256=n377iZDBGMivMvm_Ar
371
371
  udata/migrations/2021-07-05-remove-unused-badges.py,sha256=KJdDgCkCCevsmZ1n-xHnUwYgMK4MmgM67UEE_8oDdAA,921
372
372
  udata/migrations/2021-07-07-update-schema-for-community-resources.py,sha256=gj-CAQsGQ_lc7bmgZSo6sMqKLjgIYaLQShfC42Lql8w,866
373
373
  udata/migrations/2021-08-17-follow-integrity.py,sha256=wUpsXwTCaXFdhFW3zltvswm_Z0d0RafYsEandgJJ1QQ,532
374
- udata/migrations/2021-08-17-harvest-integrity.py,sha256=L0mEqlY6ekspIpPFq93grI6Gn1tT_Ii1WHaq_ORAMbU,1611
374
+ udata/migrations/2021-08-17-harvest-integrity.py,sha256=pm9ofGmXay1DMmlB2K-VsAOPqwLrKUFvOsWC8x9Zi7w,2013
375
375
  udata/migrations/2021-08-17-oauth2client-integrity.py,sha256=SP8xqZCIBrNfFDlDMU4zcq5JaXdJ__qm19QtsGNvQic,598
376
376
  udata/migrations/2021-08-17-transfer-integrity.py,sha256=zXVwwS7YnsiXB7sY0fPSOXXTzJb0aRyJWVK4cT-SAcM,607
377
377
  udata/migrations/2021-08-17-users-integrity.py,sha256=IwRsIy0iQYzSm0-ESbfu7jjemRrm0o5RVRhJstllIKY,2094
@@ -408,6 +408,7 @@ udata/migrations/2025-10-29-harvesters-sources-integrity.py,sha256=tt8ThVhtgiBSv
408
408
  udata/migrations/2025-10-31-create-membership-request-notifications.py,sha256=CZfUG7024dQj-Lz9fyp0duoATeBLlGSGb-8Gvr9B97Y,2228
409
409
  udata/migrations/2025-11-13-delete-user-email-index.py,sha256=3fSkKzDxaA-DDHRUAMg-IVFNsQrEHw8cFsDsZPX6dqE,569
410
410
  udata/migrations/2025-12-04-add-uuid-to-discussion-messages.py,sha256=DODVCMMvBP1pF4mY69nK1tzYPMFuR51bfuEciron_mg,759
411
+ udata/migrations/2025-12-16-create-transfer-request-notifications.py,sha256=ewo3SexZ9a8jlDM1k1c4gxA741NvHORM42kVeShZoSc,2681
411
412
  udata/models/__init__.py,sha256=Z3RLj1KIFNc4RZCqHNtIrMm7RZ_5_60HLL9H5nS4lUk,1198
412
413
  udata/mongo/__init__.py,sha256=y4Rv-kq3o_kcEulcNpePLzocXPBNpx3Jd82G-VZPaMc,1421
413
414
  udata/mongo/datetime_fields.py,sha256=xACagQZu1OKPvpcznI-bMC1tJfAvo-VBUe7OOadnBdg,2089
@@ -466,7 +467,7 @@ udata/tests/test_routing.py,sha256=oOO_vxS2hc0YuDbr8S7rgKTj5HSrxjjkTqSgcDoxmR0,1
466
467
  udata/tests/test_storages.py,sha256=jJ74ieRNDk5IiqW28HTifksa5_vNey_cmqdvZ0nSRVs,9813
467
468
  udata/tests/test_tags.py,sha256=vIkI7FfWii6irMLJr7FuuugJGWZ0tTJAe58W8zu34rk,3732
468
469
  udata/tests/test_topics.py,sha256=KKcvsnRzdTy0n3jM2pG6G-CIj3qMfwCGhp0CluBFDLk,6209
469
- udata/tests/test_transfer.py,sha256=Ds3milUm9cblUvB6YNuMXDr3BBxAGBcfGIKS2y20vZc,7844
470
+ udata/tests/test_transfer.py,sha256=hVwn4ZWNMChgc0A9iPv1MZHg-KOcFnkRZXM3FwtDVG4,12025
470
471
  udata/tests/test_uris.py,sha256=RZpWlmR4nAVjBnzOubI3BdNie_skgJc75ES92QOJAjk,9714
471
472
  udata/tests/test_utils.py,sha256=3BGnlvw-GOE6tLHQteo-uUeYuzq4rsjePOuytFGkpOg,7967
472
473
  udata/tests/api/__init__.py,sha256=ByLEucyyN2y-hqEF8N9C_Qreo5mEjgwu1ej5Yd-GPY4,7065
@@ -488,10 +489,11 @@ udata/tests/api/test_tags_api.py,sha256=7XROh60k0rI9lzzJbFagbSEtE3nFdx3cnHNdOxix
488
489
  udata/tests/api/test_transfer_api.py,sha256=uYeouDL42X8ruzclgaVOa6VCA3_wc8Hq8HLa8jgpZyM,7485
489
490
  udata/tests/api/test_user_api.py,sha256=Xi4vcG1cpdh7L669tWdSUwOLUvD4E4qf_ShnoyBNwUU,16854
490
491
  udata/tests/apiv2/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
492
+ udata/tests/apiv2/test_dataservices.py,sha256=-eg9ztOdFkgbXVrLZnv4uzwqxqMBS560HayR67Zjkng,550
491
493
  udata/tests/apiv2/test_datasets.py,sha256=lugL_CE2MlP4R--GEersBIwJOn66xVmLz5lU8L4YpcA,23216
492
494
  udata/tests/apiv2/test_me_api.py,sha256=YxSCtZBlSXgzQPgwMJoZHMcpSoKjL6IKz2jhJi8xL5I,1399
493
- udata/tests/apiv2/test_organizations.py,sha256=JqQHnOzRLR4l19P-EC9k2VToLbebU7jYESY4T-Y9LS8,6370
494
- udata/tests/apiv2/test_search.py,sha256=PW6vzchc-OUVH80kPIHdShqyD0lvbDmupa-DLjyT1QQ,1233
495
+ udata/tests/apiv2/test_organizations.py,sha256=rWIoYLL5-vP_pvX0W-H9YigAp64LYTLhJE-XhmFqNGs,6721
496
+ udata/tests/apiv2/test_reuses.py,sha256=zxS_YrsR4-c8gjFek711Mm057hPkyskcD0l6qi1852I,408
495
497
  udata/tests/apiv2/test_swagger.py,sha256=fIwblhKFnbXnLJb_Qs33P0c44LRm0c1JODblKEcf_4M,832
496
498
  udata/tests/apiv2/test_topics.py,sha256=pHHsPo7Qs8DoDqLBBcB0GtoptkHHXT25Jo96B2Vg_4k,37970
497
499
  udata/tests/cli/test_cli_base.py,sha256=opaL3La-ig47wpak7A-zdRUzj2hIXIYXD_0t842YrBQ,465
@@ -507,7 +509,7 @@ udata/tests/dataset/test_dataset_actions.py,sha256=8d-6AUKCt3Nnb_uEaztV0BzNYFDyq
507
509
  udata/tests/dataset/test_dataset_commands.py,sha256=e-tLIveg_Vp7nfOd5VhcPSiUQZ-VBv2no2lAu-2j6BE,820
508
510
  udata/tests/dataset/test_dataset_events.py,sha256=tKCQ55y_pc0wOKv2B2iej5dDxWalguU9FLtr6J2y8hE,3682
509
511
  udata/tests/dataset/test_dataset_model.py,sha256=YWhQ6RxVdgUrQbtvwATzypyl8XyNpdDjHDetyK37chU,35795
510
- udata/tests/dataset/test_dataset_rdf.py,sha256=RVIib5ah3B_wpTj9swbx4XSzUGyYj9_6kP_n416bnSQ,58782
512
+ udata/tests/dataset/test_dataset_rdf.py,sha256=__jm3_J5-r1u9YaBZPNFYaPlYCQ6Rt4Qr5elA-WKVzw,60503
511
513
  udata/tests/dataset/test_dataset_recommendations.py,sha256=UMwAsLHs6_XA1vp7-lnTjaPOc9E6zQYqw9VIuSCNUtk,7102
512
514
  udata/tests/dataset/test_dataset_tasks.py,sha256=6YmDBJUv3pIPNFj6DvY7FLsa4k7XxGeQ7BgOLrJOeTY,4564
513
515
  udata/tests/dataset/test_resource_preview.py,sha256=387FEdNHWZyEeOlmSETMIFlnhVuKQ-U4o2RkWgxXwik,2208
@@ -549,7 +551,7 @@ udata/tests/search/__init__.py,sha256=ub8kS6vG9EjzkJ-9sAR7j1eLSYpud1Gzry4MQ8fpgx
549
551
  udata/tests/search/test_adapter.py,sha256=4Sh8T-a8TYRMWUNe93WkVOy2b5q7i5hvjFUjXbX3UZw,8648
550
552
  udata/tests/search/test_query.py,sha256=aFZKFTJjlih5csy3eNp4MxL5hg13NqiIsrS5bCTOLrI,2182
551
553
  udata/tests/search/test_results.py,sha256=vHMkywoW6SQKGy5OtCriYpSo-KbVEdjVzOf8un2mjZE,2043
552
- udata/tests/search/test_search_integration.py,sha256=BZhoCNmvwDJV_jSYE9ILC3pmp_SeBYOiDfHfJMrwn4I,1190
554
+ udata/tests/search/test_search_integration.py,sha256=icDg7wJowl2P9ZUhFKe__MbQBH5QjLDx3d7U_fVpdAk,2623
553
555
  udata/tests/site/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
554
556
  udata/tests/site/test_site_api.py,sha256=j9pu91KfkL8-O0lyTA546cJJGZyENEauebF_uuxKVTE,1363
555
557
  udata/tests/site/test_site_csv_exports.py,sha256=XNNCUsX3Q17ov2nBOEfBLklKpwF3wxIG_1ZeayFfKls,17758
@@ -580,9 +582,9 @@ udata/translations/pt/LC_MESSAGES/udata.mo,sha256=n7ZHvruSL9hIPoSl4aCkGeC52LZYeg
580
582
  udata/translations/pt/LC_MESSAGES/udata.po,sha256=24CsHDZ84nqTMr-cOvOZ-LNYsokLQNyQchI41o3Cq9M,49765
581
583
  udata/translations/sr/LC_MESSAGES/udata.mo,sha256=pw3gsvr8lPQJZvX9Jo8ymu59I3L6-rrpX2Fqy0Nu5r4,20441
582
584
  udata/translations/sr/LC_MESSAGES/udata.po,sha256=1h8akWRpcQ1uD5zezqjp-Q-gAld5_93MkJL4BRlqKjQ,54738
583
- udata-14.5.1.dev9.dist-info/licenses/LICENSE,sha256=V8j_M8nAz8PvAOZQocyRDX7keai8UJ9skgmnwqETmdY,34520
584
- udata-14.5.1.dev9.dist-info/METADATA,sha256=HzZLmJ05MmH_cM_Dfph767hBvXEDJ7l-PC0lZ1mZ4bA,4358
585
- udata-14.5.1.dev9.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
586
- udata-14.5.1.dev9.dist-info/entry_points.txt,sha256=XwrEzP-n_6CKnwTsrNHzyCTWbMwg2FkvxVVB686f_C0,476
587
- udata-14.5.1.dev9.dist-info/top_level.txt,sha256=EF6CE6YSHd_og-8LCEA4q25ALUpWVe8D0okOLdMAE3A,6
588
- udata-14.5.1.dev9.dist-info/RECORD,,
585
+ udata-14.6.1.dev5.dist-info/licenses/LICENSE,sha256=V8j_M8nAz8PvAOZQocyRDX7keai8UJ9skgmnwqETmdY,34520
586
+ udata-14.6.1.dev5.dist-info/METADATA,sha256=XQ1_c5xX7pIahXaX898-9JNVyCqUQXsA_B-gZd0_SqI,4358
587
+ udata-14.6.1.dev5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
588
+ udata-14.6.1.dev5.dist-info/entry_points.txt,sha256=XwrEzP-n_6CKnwTsrNHzyCTWbMwg2FkvxVVB686f_C0,476
589
+ udata-14.6.1.dev5.dist-info/top_level.txt,sha256=EF6CE6YSHd_og-8LCEA4q25ALUpWVe8D0okOLdMAE3A,6
590
+ udata-14.6.1.dev5.dist-info/RECORD,,
@@ -1,30 +0,0 @@
1
- from udata.core.dataservices.factories import DataserviceFactory
2
- from udata.core.organization.factories import OrganizationFactory
3
- from udata.core.reuse.factories import ReuseFactory
4
- from udata.tests.api import APITestCase
5
-
6
-
7
- class SearchAPIV2Test(APITestCase):
8
- def test_dataservice_search_with_model_query_param(self):
9
- """Searching dataservices with 'model' as query param should not crash.
10
-
11
- Regression test for: TypeError: query() got multiple values for argument 'model'
12
- """
13
- DataserviceFactory.create_batch(3)
14
-
15
- response = self.get("/api/2/dataservices/search/?model=malicious")
16
- self.assert200(response)
17
-
18
- def test_reuse_search_with_model_query_param(self):
19
- """Searching reuses with 'model' as query param should not crash."""
20
- ReuseFactory.create_batch(3)
21
-
22
- response = self.get("/api/2/reuses/search/?model=malicious")
23
- self.assert200(response)
24
-
25
- def test_organization_search_with_model_query_param(self):
26
- """Searching organizations with 'model' as query param should not crash."""
27
- OrganizationFactory.create_batch(3)
28
-
29
- response = self.get("/api/2/organizations/search/?model=malicious")
30
- self.assert200(response)