udata 9.2.2.dev31578__py2.py3-none-any.whl → 9.2.2.dev31595__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.

@@ -6,6 +6,10 @@ from flask_security import current_user
6
6
 
7
7
  from udata.api import API, api, fields
8
8
  from udata.auth import admin_permission
9
+ from udata.core.dataservices.models import Dataservice
10
+ from udata.core.dataset.models import Dataset
11
+ from udata.core.organization.models import Organization
12
+ from udata.core.reuse.models import Reuse
9
13
  from udata.core.spam.api import SpamAPIMixin
10
14
  from udata.core.spam.fields import spam_fields
11
15
  from udata.core.user.api_fields import user_ref_fields
@@ -73,8 +77,15 @@ comment_discussion_fields = api.model(
73
77
  discussion_page_fields = api.model("DiscussionPage", fields.pager(discussion_fields))
74
78
 
75
79
  parser = api.parser()
80
+ sorting_keys: list[str] = ["created", "title", "closed"]
81
+ sorting_choices: list[str] = sorting_keys + ["-" + k for k in sorting_keys]
76
82
  parser.add_argument(
77
- "sort", type=str, default="-created", location="args", help="The sorting attribute"
83
+ "sort",
84
+ type=str,
85
+ default="-created",
86
+ choices=sorting_choices,
87
+ location="args",
88
+ help="The field (and direction) on which sorting apply",
78
89
  )
79
90
  parser.add_argument(
80
91
  "closed",
@@ -85,6 +96,9 @@ parser.add_argument(
85
96
  parser.add_argument(
86
97
  "for", type=str, location="args", action="append", help="Filter discussions for a given subject"
87
98
  )
99
+ parser.add_argument(
100
+ "org", type=str, location="args", help="Filter discussions for a given organization"
101
+ )
88
102
  parser.add_argument("user", type=str, location="args", help="Filter discussions created by a user")
89
103
  parser.add_argument("page", type=int, default=1, location="args", help="The page to fetch")
90
104
  parser.add_argument(
@@ -198,6 +212,15 @@ class DiscussionsAPI(API):
198
212
  discussions = Discussion.objects
199
213
  if args["for"]:
200
214
  discussions = discussions.generic_in(subject=args["for"])
215
+ if args["org"]:
216
+ org = Organization.objects.get_or_404(id=id_or_404(args["org"]))
217
+ if not org:
218
+ api.abort(404, "Organization does not exist")
219
+ reuses = Reuse.objects(organization=org).only("id")
220
+ datasets = Dataset.objects(organization=org).only("id")
221
+ dataservices = Dataservice.objects(organization=org).only("id")
222
+ subjects = list(reuses) + list(datasets) + list(dataservices)
223
+ discussions = discussions(subject__in=subjects)
201
224
  if args["user"]:
202
225
  discussions = discussions(discussion__posted_by=ObjectId(args["user"]))
203
226
  if args["closed"] is False:
@@ -2,8 +2,11 @@ from datetime import datetime
2
2
 
3
3
  import pytest
4
4
  from flask import url_for
5
+ from werkzeug.test import TestResponse
5
6
 
7
+ from udata.core.dataservices.factories import DataserviceFactory
6
8
  from udata.core.dataset.factories import DatasetFactory
9
+ from udata.core.discussions.factories import DiscussionFactory
7
10
  from udata.core.discussions.metrics import update_discussions_metric # noqa
8
11
  from udata.core.discussions.models import Discussion, Message
9
12
  from udata.core.discussions.notifications import discussions_notifications
@@ -19,8 +22,11 @@ from udata.core.discussions.tasks import (
19
22
  notify_new_discussion_comment,
20
23
  )
21
24
  from udata.core.organization.factories import OrganizationFactory
25
+ from udata.core.organization.models import Organization
26
+ from udata.core.reuse.factories import ReuseFactory
22
27
  from udata.core.spam.signals import on_new_potential_spam
23
28
  from udata.core.user.factories import AdminFactory, UserFactory
29
+ from udata.core.user.models import User
24
30
  from udata.models import Dataset, Member
25
31
  from udata.tests.helpers import capture_mails
26
32
  from udata.utils import faker
@@ -358,6 +364,61 @@ class DiscussionsTest(APITestCase):
358
364
 
359
365
  self.assertEqual(len(response.json["data"]), len(discussions))
360
366
 
367
+ def assertIdIn(self, json_data: dict, id_: str) -> None:
368
+ for item in json_data:
369
+ if item["id"] == id_:
370
+ return
371
+ self.fail(f"id {id_} not in {json_data}")
372
+
373
+ def test_list_discussions_org_does_not_exist(self) -> None:
374
+ response: TestResponse = self.get(url_for("api.discussions", org="bad org id"))
375
+ self.assert404(response)
376
+
377
+ def test_list_discussions_org(self) -> None:
378
+ organization: Organization = OrganizationFactory()
379
+ user: User = UserFactory()
380
+ _discussion: Discussion = DiscussionFactory(user=user)
381
+ dataset = DatasetFactory(organization=organization)
382
+ dataservice = DataserviceFactory(organization=organization)
383
+ reuse = ReuseFactory(organization=organization)
384
+ discussion_for_dataset: Discussion = DiscussionFactory(subject=dataset, user=user)
385
+ discussion_for_dataservice: Discussion = DiscussionFactory(subject=dataservice, user=user)
386
+ discussion_for_reuse: Discussion = DiscussionFactory(subject=reuse, user=user)
387
+
388
+ response: TestResponse = self.get(url_for("api.discussions", org=organization.id))
389
+ self.assert200(response)
390
+ self.assertEqual(len(response.json["data"]), 3)
391
+ self.assertIdIn(response.json["data"], str(discussion_for_dataset.id))
392
+ self.assertIdIn(response.json["data"], str(discussion_for_dataservice.id))
393
+ self.assertIdIn(response.json["data"], str(discussion_for_reuse.id))
394
+
395
+ def test_list_discussions_sort(self) -> None:
396
+ user: User = UserFactory()
397
+ sorting_keys_dict: dict = {
398
+ "title": ["aaa", "bbb"],
399
+ "created": ["2023-12-12", "2024-01-01"],
400
+ "closed": ["2023-12-12", "2024-01-01"],
401
+ }
402
+ for sorting_key, values in sorting_keys_dict.items():
403
+ discussion1: Discussion = DiscussionFactory(user=user, **{sorting_key: values[0]})
404
+ discussion2: Discussion = DiscussionFactory(user=user, **{sorting_key: values[1]})
405
+
406
+ response: TestResponse = self.get(url_for("api.discussions", sort=sorting_key))
407
+ self.assert200(response)
408
+ self.assertEqual(len(response.json["data"]), 2)
409
+ self.assertEqual(response.json["data"][0]["id"], str(discussion1.id))
410
+ self.assertEqual(response.json["data"][1]["id"], str(discussion2.id))
411
+
412
+ # Reverse sort
413
+ response: TestResponse = self.get(url_for("api.discussions", sort="-" + sorting_key))
414
+ self.assert200(response)
415
+ self.assertEqual(len(response.json["data"]), 2)
416
+ self.assertEqual(response.json["data"][0]["id"], str(discussion2.id))
417
+ self.assertEqual(response.json["data"][1]["id"], str(discussion1.id))
418
+
419
+ # Clean slate
420
+ Discussion.objects.delete()
421
+
361
422
  def test_list_discussions_user(self):
362
423
  dataset = DatasetFactory()
363
424
  discussions = []
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: udata
3
- Version: 9.2.2.dev31578
3
+ Version: 9.2.2.dev31595
4
4
  Summary: Open data portal
5
5
  Home-page: https://github.com/opendatateam/udata
6
6
  Author: Opendata Team
@@ -140,7 +140,7 @@ It is collectively taken care of by members of the
140
140
 
141
141
  ## Current (in progress)
142
142
 
143
- - Nothing yet
143
+ - Add a filter on organization and document sort parameters in the `/discussions` endpoint [#3147](https://github.com/opendatateam/udata/pull/3147)
144
144
 
145
145
  ## 9.2.1 (2024-09-23)
146
146
 
@@ -108,7 +108,7 @@ udata/core/dataset/signals.py,sha256=WN4sV-lJlNsRkhcnhoy0SYJvCoYmK_5QFYZd1u-h4gs
108
108
  udata/core/dataset/tasks.py,sha256=yDPK2oKSzTXfST8Up7vMd13XPEK5r6iapq7hUIow6BI,8493
109
109
  udata/core/discussions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
110
110
  udata/core/discussions/actions.py,sha256=seKxsKut6xLkobfC2Yy2wpD_-flsT8HcFPcN6SDpz6k,789
111
- udata/core/discussions/api.py,sha256=Fjt6F04jRHwYrtMYcokjfDxBQqRJWgyh1H5jrDyLtvA,8376
111
+ udata/core/discussions/api.py,sha256=YsVz7JB7RazAeiydxGe1q1t8sIpxCM_w1b71oT9oN_8,9422
112
112
  udata/core/discussions/constants.py,sha256=nbZgXESpg0TykIGPxW8xUtHtk7TwQoyOL0Ky4U4B7c8,27
113
113
  udata/core/discussions/factories.py,sha256=CgQaUmmyDu90XtyBsqXVa-TmZMrN7Dwuu1Cnr5wNrVc,350
114
114
  udata/core/discussions/forms.py,sha256=CalmOTslnfBY-SJatvqN2UjFJ-1S1rF57sbW8UbvmPE,838
@@ -580,7 +580,7 @@ udata/tests/plugin.py,sha256=dT3KfQiVYwLM61TbB894wzTelnlPIsCHaiPEH-Jirfk,11580
580
580
  udata/tests/schemas.json,sha256=szM1jDpkogfOG4xWbjIGjLgG8l9-ZyE3JKQtecJyD1E,4990
581
581
  udata/tests/test_activity.py,sha256=x-pDK6VW9wAG0uxYRZQ3DWTRjfCU729iaMGMJb1rWYU,3195
582
582
  udata/tests/test_cors.py,sha256=b_pyxKeIyqhnsXxXryPf4d0V0QxaLQ1P_VjY89Q_j3g,3233
583
- udata/tests/test_discussions.py,sha256=UN2mlZp-h3m3HqdF_nz9WOxwPKgXok47E2Rrp2dknYI,30464
583
+ udata/tests/test_discussions.py,sha256=Qo7nhIUY7YAATZfWl5Mgo0XhngGwFULgqEoMhsHZtFE,33587
584
584
  udata/tests/test_i18n.py,sha256=u60344JNRG_8s0t89ghXtQ1FbF4TayEHBzuBFxqnQ_Y,3152
585
585
  udata/tests/test_linkchecker.py,sha256=W8jrwKYXM8wWXZFjiaBwpWGRBhZ8bsSHGHzL9voDN7U,10218
586
586
  udata/tests/test_mail.py,sha256=ijcrniawbvftm5UF8KDApBoxMHyZwULAA25LrnLmeI8,1629
@@ -697,9 +697,9 @@ udata/translations/pt/LC_MESSAGES/udata.mo,sha256=WpPzAqVd2Onv_kz45ULUySKPLrpjcc
697
697
  udata/translations/pt/LC_MESSAGES/udata.po,sha256=18Op9RUITewoDRewlOdYzzq6gjsf1lsvepACV1d7zxs,44976
698
698
  udata/translations/sr/LC_MESSAGES/udata.mo,sha256=NIYRNhVoETZUvIvWm3cCW7DtMBAnS2vXzZjMF5ZzD_c,28500
699
699
  udata/translations/sr/LC_MESSAGES/udata.po,sha256=rQB-4V4WJ7bURj6g2j653vItr5TMHadcLQxec7_fDmg,51545
700
- udata-9.2.2.dev31578.dist-info/LICENSE,sha256=V8j_M8nAz8PvAOZQocyRDX7keai8UJ9skgmnwqETmdY,34520
701
- udata-9.2.2.dev31578.dist-info/METADATA,sha256=A2qsgIGm1QV5SmTZqksgcyjwSYuG5jEt6DwbmfD_0i8,130894
702
- udata-9.2.2.dev31578.dist-info/WHEEL,sha256=DZajD4pwLWue70CAfc7YaxT1wLUciNBvN_TTcvXpltE,110
703
- udata-9.2.2.dev31578.dist-info/entry_points.txt,sha256=3SKiqVy4HUqxf6iWspgMqH8d88Htk6KoLbG1BU-UddQ,451
704
- udata-9.2.2.dev31578.dist-info/top_level.txt,sha256=39OCg-VWFWOq4gCKnjKNu-s3OwFlZIu_dVH8Gl6ndHw,12
705
- udata-9.2.2.dev31578.dist-info/RECORD,,
700
+ udata-9.2.2.dev31595.dist-info/LICENSE,sha256=V8j_M8nAz8PvAOZQocyRDX7keai8UJ9skgmnwqETmdY,34520
701
+ udata-9.2.2.dev31595.dist-info/METADATA,sha256=HGZs0bXBUTcDx6EIpQ6SBOQe3-fTCuLZe3CGI_XfFZ0,131028
702
+ udata-9.2.2.dev31595.dist-info/WHEEL,sha256=DZajD4pwLWue70CAfc7YaxT1wLUciNBvN_TTcvXpltE,110
703
+ udata-9.2.2.dev31595.dist-info/entry_points.txt,sha256=3SKiqVy4HUqxf6iWspgMqH8d88Htk6KoLbG1BU-UddQ,451
704
+ udata-9.2.2.dev31595.dist-info/top_level.txt,sha256=39OCg-VWFWOq4gCKnjKNu-s3OwFlZIu_dVH8Gl6ndHw,12
705
+ udata-9.2.2.dev31595.dist-info/RECORD,,