udata 9.1.2.dev30754__py2.py3-none-any.whl → 9.1.4.dev30983__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.

Files changed (90) hide show
  1. tasks/helpers.py +6 -5
  2. udata/__init__.py +1 -1
  3. udata/api/__init__.py +2 -3
  4. udata/api/commands.py +0 -1
  5. udata/api/fields.py +22 -1
  6. udata/api_fields.py +22 -12
  7. udata/app.py +1 -1
  8. udata/assets.py +1 -1
  9. udata/auth/__init__.py +8 -12
  10. udata/commands/db.py +3 -3
  11. udata/commands/dcat.py +1 -1
  12. udata/commands/fixtures.py +110 -54
  13. udata/commands/init.py +2 -2
  14. udata/commands/tests/test_fixtures.py +71 -0
  15. udata/core/activity/tasks.py +1 -1
  16. udata/core/badges/models.py +0 -2
  17. udata/core/contact_point/api.py +1 -3
  18. udata/core/dataservices/tasks.py +1 -1
  19. udata/core/dataset/actions.py +2 -2
  20. udata/core/dataset/forms.py +0 -2
  21. udata/core/dataset/models.py +12 -10
  22. udata/core/dataset/rdf.py +1 -1
  23. udata/core/discussions/api.py +1 -1
  24. udata/core/discussions/models.py +2 -2
  25. udata/core/discussions/tasks.py +1 -1
  26. udata/core/organization/api.py +3 -4
  27. udata/core/organization/api_fields.py +2 -1
  28. udata/core/organization/apiv2.py +1 -1
  29. udata/core/reports/api.py +11 -0
  30. udata/core/reports/models.py +6 -1
  31. udata/core/reuse/metrics.py +1 -1
  32. udata/core/reuse/permissions.py +2 -1
  33. udata/core/reuse/search.py +2 -2
  34. udata/core/reuse/tasks.py +2 -2
  35. udata/core/spatial/commands.py +3 -3
  36. udata/core/spatial/factories.py +1 -1
  37. udata/core/spatial/forms.py +1 -1
  38. udata/core/spatial/models.py +2 -2
  39. udata/core/spatial/tests/test_models.py +1 -1
  40. udata/core/spatial/translations.py +3 -1
  41. udata/core/user/api.py +4 -4
  42. udata/core/user/metrics.py +1 -1
  43. udata/frontend/__init__.py +1 -1
  44. udata/harvest/actions.py +1 -1
  45. udata/harvest/backends/__init__.py +1 -1
  46. udata/harvest/tasks.py +0 -1
  47. udata/harvest/tests/factories.py +0 -2
  48. udata/harvest/tests/test_base_backend.py +0 -1
  49. udata/harvest/tests/test_dcat_backend.py +16 -17
  50. udata/migrations/2020-07-24-remove-s-from-scope-oauth.py +1 -1
  51. udata/migrations/2021-07-05-remove-unused-badges.py +0 -1
  52. udata/migrations/2023-02-08-rename-internal-dates.py +0 -2
  53. udata/migrations/2024-06-11-fix-reuse-datasets-references.py +0 -1
  54. udata/models/__init__.py +1 -0
  55. udata/routing.py +5 -0
  56. udata/search/commands.py +1 -1
  57. udata/search/query.py +1 -1
  58. udata/sentry.py +11 -2
  59. udata/settings.py +1 -0
  60. udata/tags.py +3 -3
  61. udata/tests/api/test_base_api.py +1 -1
  62. udata/tests/api/test_contact_points.py +4 -4
  63. udata/tests/api/test_datasets_api.py +10 -10
  64. udata/tests/api/test_organizations_api.py +39 -39
  65. udata/tests/api/test_reports_api.py +53 -3
  66. udata/tests/api/test_tags_api.py +2 -2
  67. udata/tests/api/test_transfer_api.py +1 -1
  68. udata/tests/apiv2/test_datasets.py +4 -4
  69. udata/tests/dataset/test_dataset_model.py +3 -3
  70. udata/tests/frontend/__init__.py +0 -2
  71. udata/tests/frontend/test_auth.py +0 -1
  72. udata/tests/organization/test_csv_adapter.py +0 -2
  73. udata/tests/organization/test_notifications.py +3 -3
  74. udata/tests/reuse/test_reuse_model.py +0 -1
  75. udata/tests/site/test_site_rdf.py +1 -3
  76. udata/tests/test_cors.py +0 -3
  77. udata/tests/test_owned.py +4 -4
  78. udata/tests/test_routing.py +1 -1
  79. udata/tests/test_tags.py +1 -1
  80. udata/tests/test_transfer.py +1 -2
  81. udata/tests/workers/test_jobs_commands.py +1 -1
  82. udata/utils.py +15 -14
  83. {udata-9.1.2.dev30754.dist-info → udata-9.1.4.dev30983.dist-info}/METADATA +20 -4
  84. {udata-9.1.2.dev30754.dist-info → udata-9.1.4.dev30983.dist-info}/RECORD +88 -89
  85. udata/commands/tests/fixtures.py +0 -44
  86. udata/tests/features/territories/commands.py +0 -9
  87. {udata-9.1.2.dev30754.dist-info → udata-9.1.4.dev30983.dist-info}/LICENSE +0 -0
  88. {udata-9.1.2.dev30754.dist-info → udata-9.1.4.dev30983.dist-info}/WHEEL +0 -0
  89. {udata-9.1.2.dev30754.dist-info → udata-9.1.4.dev30983.dist-info}/entry_points.txt +0 -0
  90. {udata-9.1.2.dev30754.dist-info → udata-9.1.4.dev30983.dist-info}/top_level.txt +0 -0
udata/search/query.py CHANGED
@@ -3,7 +3,7 @@ import logging
3
3
  import urllib.parse
4
4
 
5
5
  import requests
6
- from flask import current_app, request, url_for
6
+ from flask import current_app, request
7
7
 
8
8
  from udata.search.result import SearchResult
9
9
 
udata/sentry.py CHANGED
@@ -8,7 +8,9 @@ from werkzeug.exceptions import HTTPException
8
8
  from udata import entrypoints
9
9
  from udata.core.storages.api import UploadProgress
10
10
 
11
+ from .app import UDataApp
11
12
  from .auth import PermissionDenied
13
+ from .frontend import package_version
12
14
 
13
15
  log = logging.getLogger(__name__)
14
16
 
@@ -24,7 +26,7 @@ ERROR_PARSE_DSN_MSG = "Unable to parse Sentry DSN"
24
26
  IGNORED_EXCEPTIONS = HTTPException, PermissionDenied, UploadProgress
25
27
 
26
28
 
27
- def public_dsn(dsn):
29
+ def public_dsn(dsn: str) -> str | None:
28
30
  """Check if DSN is public or raise a warning and turn it into a public one"""
29
31
  m = RE_DSN.match(dsn)
30
32
  if not m:
@@ -41,7 +43,7 @@ def public_dsn(dsn):
41
43
  return public
42
44
 
43
45
 
44
- def init_app(app):
46
+ def init_app(app: UDataApp):
45
47
  if app.config["SENTRY_DSN"]:
46
48
  try:
47
49
  import sentry_sdk
@@ -62,6 +64,13 @@ def init_app(app):
62
64
  dsn=app.config["SENTRY_PUBLIC_DSN"],
63
65
  integrations=[FlaskIntegration(), CeleryIntegration()],
64
66
  ignore_errors=list(exceptions),
67
+ release=f"udata@{package_version('udata')}",
68
+ environment=app.config.get("SITE_ID", None),
69
+ # Set traces_sample_rate to 1.0 to capture 100%
70
+ # of transactions for performance monitoring.
71
+ # Sentry recommends adjusting this value in production.
72
+ traces_sample_rate=app.config.get("SENTRY_SAMPLE_RATE", None),
73
+ profiles_sample_rate=app.config.get("SENTRY_SAMPLE_RATE", None),
65
74
  )
66
75
 
67
76
  # Set log level
udata/settings.py CHANGED
@@ -113,6 +113,7 @@ class Defaults(object):
113
113
  SENTRY_USER_ATTRS = ["slug", "email", "fullname"]
114
114
  SENTRY_LOGGING = "WARNING"
115
115
  SENTRY_IGNORE_EXCEPTIONS = []
116
+ SENTRY_SAMPLE_RATE: float = 1.0
116
117
 
117
118
  # Flask WTF settings
118
119
  CSRF_SESSION_KEY = "Default uData csrf key"
udata/tags.py CHANGED
@@ -6,11 +6,11 @@ MIN_TAG_LENGTH = LocalProxy(lambda: current_app.config["TAG_MIN_LENGTH"])
6
6
  MAX_TAG_LENGTH = LocalProxy(lambda: current_app.config["TAG_MAX_LENGTH"])
7
7
 
8
8
 
9
- def slug(value):
9
+ def slug(value: str) -> str:
10
10
  return slugify(value.lower())
11
11
 
12
12
 
13
- def normalize(value):
13
+ def normalize(value: str) -> str:
14
14
  value = slug(value)
15
15
  if len(value) < MIN_TAG_LENGTH:
16
16
  value = ""
@@ -19,5 +19,5 @@ def normalize(value):
19
19
  return value
20
20
 
21
21
 
22
- def tags_list(value):
22
+ def tags_list(value: str) -> list:
23
23
  return list(set(slug(tag) for tag in value.split(",") if tag.strip()))
@@ -1,7 +1,7 @@
1
1
  from flask import url_for
2
2
 
3
3
  from udata.api import API, api
4
- from udata.forms import Form, fields
4
+ from udata.forms import Form
5
5
 
6
6
  from . import APITestCase
7
7
 
@@ -14,18 +14,18 @@ class ContactPointAPITest:
14
14
  modules = []
15
15
 
16
16
  def test_contact_point_api_update(self, api):
17
- user = api.login()
17
+ api.login()
18
18
  contact_point = ContactPointFactory()
19
19
  data = contact_point.to_dict()
20
20
  data["email"] = "new.email@newdomain.com"
21
21
  response = api.put(url_for("api.contact_point", contact_point=contact_point), data)
22
22
  assert200(response)
23
- assert ContactPoint.objects.count() is 1
23
+ assert ContactPoint.objects.count() == 1
24
24
  assert ContactPoint.objects.first().email == "new.email@newdomain.com"
25
25
 
26
26
  def test_contact_point_api_delete(self, api):
27
- user = api.login()
27
+ api.login()
28
28
  contact_point = ContactPointFactory()
29
29
  response = api.delete(url_for("api.contact_point", contact_point=contact_point))
30
30
  assert204(response)
31
- assert ContactPoint.objects.count() is 0
31
+ assert ContactPoint.objects.count() == 0
@@ -42,7 +42,7 @@ from udata.i18n import gettext as _
42
42
  from udata.models import CommunityResource, Dataset, Follow, Member, db
43
43
  from udata.tags import MAX_TAG_LENGTH, MIN_TAG_LENGTH
44
44
  from udata.tests.features.territories import create_geozones_fixtures
45
- from udata.tests.helpers import assert200, assert204, assert404
45
+ from udata.tests.helpers import assert200, assert404
46
46
  from udata.utils import faker, unique_string
47
47
 
48
48
  from . import APITestCase
@@ -839,7 +839,7 @@ class DatasetAPITest(APITestCase):
839
839
  dataset.reload()
840
840
  assert dataset.resources[0].schema["url"] == "http://example.com"
841
841
  assert dataset.resources[0].schema["name"] == "etalab/schema-irve-statique"
842
- assert dataset.resources[0].schema["version"] == None
842
+ assert dataset.resources[0].schema["version"] is None
843
843
 
844
844
  resource_data["schema"] = {"name": "etalab/schema-irve-statique"}
845
845
  data["resources"].append(resource_data)
@@ -848,8 +848,8 @@ class DatasetAPITest(APITestCase):
848
848
 
849
849
  dataset.reload()
850
850
  assert dataset.resources[0].schema["name"] == "etalab/schema-irve-statique"
851
- assert dataset.resources[0].schema["url"] == None
852
- assert dataset.resources[0].schema["version"] == None
851
+ assert dataset.resources[0].schema["url"] is None
852
+ assert dataset.resources[0].schema["version"] is None
853
853
 
854
854
  resource_data["schema"] = {"name": "etalab/schema-irve-statique", "version": "2.2.0"}
855
855
  data["resources"].append(resource_data)
@@ -858,7 +858,7 @@ class DatasetAPITest(APITestCase):
858
858
 
859
859
  dataset.reload()
860
860
  assert dataset.resources[0].schema["name"] == "etalab/schema-irve-statique"
861
- assert dataset.resources[0].schema["url"] == None
861
+ assert dataset.resources[0].schema["url"] is None
862
862
  assert dataset.resources[0].schema["version"] == "2.2.0"
863
863
 
864
864
  resource_data["schema"] = {
@@ -870,7 +870,7 @@ class DatasetAPITest(APITestCase):
870
870
 
871
871
  dataset.reload()
872
872
  assert dataset.resources[0].schema["name"] == "etalab/schema-irve-statique"
873
- assert dataset.resources[0].schema["url"] == None
873
+ assert dataset.resources[0].schema["url"] is None
874
874
  assert dataset.resources[0].schema["version"] == "2.2.1"
875
875
 
876
876
  # Putting `None` as the schema argument do not remove the schema
@@ -884,7 +884,7 @@ class DatasetAPITest(APITestCase):
884
884
 
885
885
  dataset.reload()
886
886
  assert dataset.resources[0].schema["name"] == "etalab/schema-irve-statique"
887
- assert dataset.resources[0].schema["url"] == None
887
+ assert dataset.resources[0].schema["url"] is None
888
888
  assert dataset.resources[0].schema["version"] == "2.2.1"
889
889
 
890
890
  # Putting `None` as the schema name and version remove the schema
@@ -897,9 +897,9 @@ class DatasetAPITest(APITestCase):
897
897
  self.assert200(response)
898
898
 
899
899
  dataset.reload()
900
- assert dataset.resources[0].schema["name"] == None
901
- assert dataset.resources[0].schema["url"] == None
902
- assert dataset.resources[0].schema["version"] == None
900
+ assert dataset.resources[0].schema["name"] is None
901
+ assert dataset.resources[0].schema["url"] is None
902
+ assert dataset.resources[0].schema["version"] is None
903
903
 
904
904
 
905
905
  class DatasetBadgeAPITest(APITestCase):
@@ -72,7 +72,7 @@ class OrganizationAPITest:
72
72
  user = api.login()
73
73
  response = api.post(url_for("api.organizations"), data)
74
74
  assert201(response)
75
- assert Organization.objects.count() is 1
75
+ assert Organization.objects.count() == 1
76
76
 
77
77
  org = Organization.objects.first()
78
78
  member = org.member(user)
@@ -89,7 +89,7 @@ class OrganizationAPITest:
89
89
  data["description"] = "new description"
90
90
  response = api.put(url_for("api.organization", org=org), data)
91
91
  assert200(response)
92
- assert Organization.objects.count() is 1
92
+ assert Organization.objects.count() == 1
93
93
  assert Organization.objects.first().description == "new description"
94
94
 
95
95
  def test_organization_api_update_business_number_id(self, api):
@@ -101,7 +101,7 @@ class OrganizationAPITest:
101
101
  data["business_number_id"] = "13002526500013"
102
102
  response = api.put(url_for("api.organization", org=org), data)
103
103
  assert200(response)
104
- assert Organization.objects.count() is 1
104
+ assert Organization.objects.count() == 1
105
105
  assert Organization.objects.first().business_number_id == "13002526500013"
106
106
 
107
107
  def test_organization_api_update_business_number_id_failing(self, api):
@@ -147,7 +147,7 @@ class OrganizationAPITest:
147
147
  api.login()
148
148
  response = api.put(url_for("api.organization", org=org), data)
149
149
  assert403(response)
150
- assert Organization.objects.count() is 1
150
+ assert Organization.objects.count() == 1
151
151
  assert Organization.objects.first().description == org.description
152
152
 
153
153
  def test_organization_api_delete(self, api):
@@ -157,7 +157,7 @@ class OrganizationAPITest:
157
157
  org = OrganizationFactory(members=[member])
158
158
  response = api.delete(url_for("api.organization", org=org))
159
159
  assert204(response)
160
- assert Organization.objects.count() is 1
160
+ assert Organization.objects.count() == 1
161
161
  assert Organization.objects[0].deleted is not None
162
162
 
163
163
  def test_organization_api_delete_deleted(self, api):
@@ -175,7 +175,7 @@ class OrganizationAPITest:
175
175
  org = OrganizationFactory(members=[member])
176
176
  response = api.delete(url_for("api.organization", org=org))
177
177
  assert403(response)
178
- assert Organization.objects.count() is 1
178
+ assert Organization.objects.count() == 1
179
179
  assert Organization.objects[0].deleted is None
180
180
 
181
181
  def test_organization_api_delete_as_non_member_forbidden(self, api):
@@ -184,7 +184,7 @@ class OrganizationAPITest:
184
184
  org = OrganizationFactory()
185
185
  response = api.delete(url_for("api.organization", org=org))
186
186
  assert403(response)
187
- assert Organization.objects.count() is 1
187
+ assert Organization.objects.count() == 1
188
188
  assert Organization.objects[0].deleted is None
189
189
 
190
190
 
@@ -200,10 +200,10 @@ class MembershipAPITest:
200
200
  assert201(response)
201
201
 
202
202
  organization.reload()
203
- assert len(organization.requests) is 1
204
- assert len(organization.pending_requests) is 1
205
- assert len(organization.refused_requests) is 0
206
- assert len(organization.accepted_requests) is 0
203
+ assert len(organization.requests) == 1
204
+ assert len(organization.pending_requests) == 1
205
+ assert len(organization.refused_requests) == 0
206
+ assert len(organization.accepted_requests) == 0
207
207
 
208
208
  request = organization.requests[0]
209
209
  assert request.user == user
@@ -223,10 +223,10 @@ class MembershipAPITest:
223
223
  assert200(response)
224
224
 
225
225
  organization.reload()
226
- assert len(organization.requests) is 1
227
- assert len(organization.pending_requests) is 1
228
- assert len(organization.refused_requests) is 0
229
- assert len(organization.accepted_requests) is 0
226
+ assert len(organization.requests) == 1
227
+ assert len(organization.pending_requests) == 1
228
+ assert len(organization.refused_requests) == 0
229
+ assert len(organization.accepted_requests) == 0
230
230
 
231
231
  request = organization.requests[0]
232
232
  assert request.user == user
@@ -326,10 +326,10 @@ class MembershipAPITest:
326
326
  assert response.json["role"] == "editor"
327
327
 
328
328
  organization.reload()
329
- assert len(organization.requests) is 1
330
- assert len(organization.pending_requests) is 0
331
- assert len(organization.refused_requests) is 0
332
- assert len(organization.accepted_requests) is 1
329
+ assert len(organization.requests) == 1
330
+ assert len(organization.pending_requests) == 0
331
+ assert len(organization.refused_requests) == 0
332
+ assert len(organization.accepted_requests) == 1
333
333
  assert organization.is_member(applicant)
334
334
 
335
335
  request = organization.requests[0]
@@ -380,10 +380,10 @@ class MembershipAPITest:
380
380
  assert200(response)
381
381
 
382
382
  organization.reload()
383
- assert len(organization.requests) is 1
384
- assert len(organization.pending_requests) is 0
385
- assert len(organization.refused_requests) is 1
386
- assert len(organization.accepted_requests) is 0
383
+ assert len(organization.requests) == 1
384
+ assert len(organization.pending_requests) == 0
385
+ assert len(organization.refused_requests) == 1
386
+ assert len(organization.accepted_requests) == 0
387
387
  assert not organization.is_member(applicant)
388
388
 
389
389
  request = organization.requests[0]
@@ -548,12 +548,12 @@ class MembershipAPITest:
548
548
  to_follow.count_followers()
549
549
  assert to_follow.get_metrics()["followers"] == 1
550
550
 
551
- assert Follow.objects.following(to_follow).count() is 0
552
- assert Follow.objects.followers(to_follow).count() is 1
551
+ assert Follow.objects.following(to_follow).count() == 0
552
+ assert Follow.objects.followers(to_follow).count() == 1
553
553
  follow = Follow.objects.followers(to_follow).first()
554
554
  assert isinstance(follow.following, Organization)
555
- assert Follow.objects.following(user).count() is 1
556
- assert Follow.objects.followers(user).count() is 0
555
+ assert Follow.objects.following(user).count() == 1
556
+ assert Follow.objects.followers(user).count() == 0
557
557
 
558
558
  def test_unfollow_org(self, api):
559
559
  """It should unfollow the organization on DELETE"""
@@ -567,12 +567,12 @@ class MembershipAPITest:
567
567
 
568
568
  nb_followers = Follow.objects.followers(to_follow).count()
569
569
 
570
- assert nb_followers is 0
570
+ assert nb_followers == 0
571
571
  assert response.json["followers"] == nb_followers
572
572
 
573
- assert Follow.objects.following(to_follow).count() is 0
574
- assert Follow.objects.following(user).count() is 0
575
- assert Follow.objects.followers(user).count() is 0
573
+ assert Follow.objects.following(to_follow).count() == 0
574
+ assert Follow.objects.following(user).count() == 0
575
+ assert Follow.objects.followers(user).count() == 0
576
576
 
577
577
  def test_suggest_organizations_api(self, api):
578
578
  """It should suggest organizations"""
@@ -658,13 +658,13 @@ class MembershipAPITest:
658
658
 
659
659
  response = api.get(url_for("api.suggest_organizations"), qs={"q": "xxxxxx", "size": "5"})
660
660
  assert200(response)
661
- assert len(response.json) is 0
661
+ assert len(response.json) == 0
662
662
 
663
663
  def test_suggest_organizations_api_empty(self, api):
664
664
  """It should not provide organization suggestion if no data"""
665
665
  response = api.get(url_for("api.suggest_organizations"), qs={"q": "xxxxxx", "size": "5"})
666
666
  assert200(response)
667
- assert len(response.json) is 0
667
+ assert len(response.json) == 0
668
668
 
669
669
  def test_suggest_organizations_homonyms(self, api):
670
670
  """It should suggest organizations and not deduplicate homonyms"""
@@ -673,7 +673,7 @@ class MembershipAPITest:
673
673
  response = api.get(url_for("api.suggest_organizations"), qs={"q": "homonym", "size": "5"})
674
674
  assert200(response)
675
675
 
676
- assert len(response.json) is 2
676
+ assert len(response.json) == 2
677
677
 
678
678
  for suggestion in response.json:
679
679
  assert suggestion["name"] == "homonym"
@@ -749,7 +749,7 @@ class OrganizationDatasetsAPITest:
749
749
  response = api.get(url_for("api.org_datasets", org=org), qs={"page_size": 2})
750
750
 
751
751
  assert200(response)
752
- assert len(response.json["data"]) is 2
752
+ assert len(response.json["data"]) == 2
753
753
 
754
754
 
755
755
  class OrganizationReusesAPITest:
@@ -841,7 +841,7 @@ class OrganizationBadgeAPITest:
841
841
  response = api.post(url, data)
842
842
  assert201(response)
843
843
  self.organization.reload()
844
- assert len(self.organization.badges) is 1
844
+ assert len(self.organization.badges) == 1
845
845
 
846
846
  def test_create_same(self, api):
847
847
  data = self.factory.as_dict()
@@ -852,7 +852,7 @@ class OrganizationBadgeAPITest:
852
852
  response = api.post(url, data)
853
853
  assert200(response)
854
854
  self.organization.reload()
855
- assert len(self.organization.badges) is 1
855
+ assert len(self.organization.badges) == 1
856
856
 
857
857
  def test_create_2nd(self, api):
858
858
  # Explicitely setting the kind to avoid collisions given the
@@ -865,7 +865,7 @@ class OrganizationBadgeAPITest:
865
865
  response = api.post(url, data)
866
866
  assert201(response)
867
867
  self.organization.reload()
868
- assert len(self.organization.badges) is 2
868
+ assert len(self.organization.badges) == 2
869
869
 
870
870
  def test_delete(self, api):
871
871
  badge = self.factory()
@@ -876,7 +876,7 @@ class OrganizationBadgeAPITest:
876
876
  response = api.delete(url)
877
877
  assert204(response)
878
878
  self.organization.reload()
879
- assert len(self.organization.badges) is 0
879
+ assert len(self.organization.badges) == 0
880
880
 
881
881
  def test_delete_404(self, api):
882
882
  kind = str(self.factory().kind)
@@ -1,5 +1,4 @@
1
1
  from flask import url_for
2
- from mongoengine.base.datastructures import LazyReference
3
2
 
4
3
  from udata.core.dataset.factories import DatasetFactory
5
4
  from udata.core.dataset.models import Dataset
@@ -9,8 +8,8 @@ from udata.core.reports.constants import (
9
8
  reports_reasons_translations,
10
9
  )
11
10
  from udata.core.reports.models import Report
12
- from udata.core.user.factories import UserFactory
13
- from udata.i18n import gettext as _
11
+ from udata.core.reuse.factories import ReuseFactory
12
+ from udata.core.user.factories import AdminFactory, UserFactory
14
13
 
15
14
  from . import APITestCase
16
15
 
@@ -100,6 +99,11 @@ class ReportsAPITest(APITestCase):
100
99
  reports[1].reload()
101
100
  self.assertIsNotNone(reports[1].subject_deleted_at)
102
101
 
102
+ # Should be logged as admin
103
+ response = self.get(url_for("api.reports"))
104
+ self.assert403(response)
105
+
106
+ self.login(AdminFactory())
103
107
  response = self.get(url_for("api.reports"))
104
108
  self.assert200(response)
105
109
 
@@ -119,3 +123,49 @@ class ReportsAPITest(APITestCase):
119
123
  self.assertEqual(REASON_SPAM, reports[1]["reason"])
120
124
  self.assertEqual(str(user.id), reports[1]["by"]["id"])
121
125
  self.assertIsNotNone(reports[1]["subject_deleted_at"])
126
+
127
+ def test_reports_api_list(self):
128
+ user = UserFactory()
129
+
130
+ spam_dataset = DatasetFactory.create(owner=user)
131
+ spam_reuse = ReuseFactory.create(owner=user)
132
+
133
+ Report(subject=spam_dataset, reason="spam").save()
134
+ Report(subject=spam_reuse, reason="spam").save()
135
+
136
+ # Should be logged as admin
137
+ response = self.get(url_for("api.reports"))
138
+ self.assert401(response)
139
+
140
+ self.login(AdminFactory())
141
+ response = self.get(url_for("api.reports"))
142
+ self.assert200(response)
143
+
144
+ payload = response.json
145
+ self.assertEqual(payload["total"], 2)
146
+ # Returned by order of creation by default
147
+ self.assertEqual(payload["data"][0]["subject"]["id"], str(spam_dataset.id))
148
+ self.assertEqual(
149
+ payload["data"][0]["self_api_url"],
150
+ url_for("api.report", report=payload["data"][0]["id"], _external=True),
151
+ )
152
+
153
+ self.assertEqual(payload["data"][1]["subject"]["id"], str(spam_reuse.id))
154
+
155
+ def test_reports_api_get(self):
156
+ user = UserFactory()
157
+
158
+ spam_dataset = DatasetFactory.create(owner=user)
159
+
160
+ report = Report(subject=spam_dataset, reason="spam").save()
161
+
162
+ # Should be logged as admin
163
+ response = self.get(url_for("api.report", report=report))
164
+ self.assert401(response)
165
+
166
+ self.login(AdminFactory())
167
+ response = self.get(url_for("api.report", report=report))
168
+ self.assert200(response)
169
+
170
+ payload = response.json
171
+ self.assertEqual(payload["subject"]["id"], str(spam_dataset.id))
@@ -61,10 +61,10 @@ class TagsAPITest:
61
61
 
62
62
  response = api.get(url_for("api.suggest_tags"), qs={"q": "bbbb", "size": "5"})
63
63
  assert200(response)
64
- assert len(response.json) is 0
64
+ assert len(response.json) == 0
65
65
 
66
66
  def test_suggest_tags_api_empty(self, api):
67
67
  """It should not provide tag suggestion if no data"""
68
68
  response = api.get(url_for("api.suggest_tags"), qs={"q": "bbbb", "size": "5"})
69
69
  assert200(response)
70
- assert len(response.json) is 0
70
+ assert len(response.json) == 0
@@ -58,7 +58,7 @@ class TransferAPITest(APITestCase):
58
58
  self.assertEqual(data["status"], "pending")
59
59
 
60
60
  def test_400_on_bad_subject(self):
61
- user = self.login()
61
+ self.login()
62
62
  recipient = UserFactory()
63
63
  comment = faker.sentence()
64
64
 
@@ -83,7 +83,7 @@ class DatasetResourceAPIV2Test(APITestCase):
83
83
  assert data["total"] == len(resources)
84
84
  assert data["page"] == 1
85
85
  assert data["page_size"] == DEFAULT_PAGE_SIZE
86
- assert data["next_page"] == None
86
+ assert data["next_page"] is None
87
87
  assert data["previous_page"] is None
88
88
 
89
89
  def test_get_missing_param(self):
@@ -97,7 +97,7 @@ class DatasetResourceAPIV2Test(APITestCase):
97
97
  assert data["total"] == len(resources)
98
98
  assert data["page"] == 1
99
99
  assert data["page_size"] == DEFAULT_PAGE_SIZE
100
- assert data["next_page"] == None
100
+ assert data["next_page"] is None
101
101
  assert data["previous_page"] is None
102
102
 
103
103
  def test_get_next_page(self):
@@ -129,7 +129,7 @@ class DatasetResourceAPIV2Test(APITestCase):
129
129
  assert data["total"] == len(resources)
130
130
  assert data["page"] == 2
131
131
  assert data["page_size"] == DEFAULT_PAGE_SIZE
132
- assert data["next_page"] == None
132
+ assert data["next_page"] is None
133
133
  assert data["previous_page"] == url_for(
134
134
  "apiv2.resources",
135
135
  dataset=dataset.id,
@@ -196,7 +196,7 @@ class DatasetResourceAPIV2Test(APITestCase):
196
196
  assert data["total"] == nb_resources__of_specific_type
197
197
  assert data["page"] == 2
198
198
  assert data["page_size"] == DEFAULT_PAGE_SIZE
199
- assert data["next_page"] == None
199
+ assert data["next_page"] is None
200
200
  assert data["previous_page"] == url_for(
201
201
  "apiv2.resources",
202
202
  dataset=dataset.id,
@@ -301,15 +301,15 @@ class DatasetModelTest:
301
301
 
302
302
  def test_dataset_without_private(self):
303
303
  dataset = DatasetFactory()
304
- assert dataset.private == False
304
+ assert dataset.private is False
305
305
 
306
306
  dataset.private = None
307
307
  dataset.save()
308
- assert dataset.private == False
308
+ assert dataset.private is False
309
309
 
310
310
  dataset.private = True
311
311
  dataset.save()
312
- assert dataset.private == True
312
+ assert dataset.private is True
313
313
 
314
314
 
315
315
  class ResourceModelTest:
@@ -1,8 +1,6 @@
1
1
  import json
2
2
  import re
3
3
 
4
- import pytest
5
-
6
4
  from udata.tests import DBTestMixin, TestCase, WebTestMixin
7
5
 
8
6
 
@@ -11,7 +11,6 @@ class AuthTest(FrontTestCase):
11
11
 
12
12
  def test_change_mail(self):
13
13
  user = self.login(AdminFactory())
14
- url = url_for("security.change_email")
15
14
 
16
15
  new_email = "test@test.com"
17
16
 
@@ -1,8 +1,6 @@
1
1
  import pytest
2
2
 
3
- from udata.core.dataset.csv import DatasetCsvAdapter, ResourcesCsvAdapter
4
3
  from udata.core.dataset.factories import DatasetFactory, ResourceFactory
5
- from udata.core.dataset.models import Dataset
6
4
  from udata.core.organization.csv import OrganizationCsvAdapter
7
5
  from udata.core.organization.factories import OrganizationFactory
8
6
  from udata.core.organization.models import Organization
@@ -17,11 +17,11 @@ class OrganizationNotificationsTest:
17
17
  members = [Member(user=editor, role="editor"), Member(user=admin, role="admin")]
18
18
  org = OrganizationFactory(members=members, requests=[request])
19
19
 
20
- assert len(membership_request_notifications(applicant)) is 0
21
- assert len(membership_request_notifications(editor)) is 0
20
+ assert len(membership_request_notifications(applicant)) == 0
21
+ assert len(membership_request_notifications(editor)) == 0
22
22
 
23
23
  notifications = membership_request_notifications(admin)
24
- assert len(notifications) is 1
24
+ assert len(notifications) == 1
25
25
  dt, details = notifications[0]
26
26
  assert_equal_dates(dt, request.created)
27
27
  assert details["id"] == request.id
@@ -1,4 +1,3 @@
1
- import re
2
1
  from datetime import datetime
3
2
 
4
3
  from udata.core.dataset import tasks as dataset_tasks
@@ -254,9 +254,7 @@ class SiteRdfViewsTest:
254
254
  dataset_b = DatasetFactory.create()
255
255
  dataset_c = DatasetFactory.create()
256
256
 
257
- dataservice_a = DataserviceFactory.create(
258
- datasets=[dataset_a.id], harvest=HarvestMetadataFactory()
259
- )
257
+ DataserviceFactory.create(datasets=[dataset_a.id], harvest=HarvestMetadataFactory())
260
258
  dataservice_b = DataserviceFactory.create(datasets=[dataset_b.id])
261
259
  dataservice_x = DataserviceFactory.create(datasets=[dataset_a.id, dataset_c.id])
262
260
  dataservice_y = DataserviceFactory.create(datasets=[])
udata/tests/test_cors.py CHANGED
@@ -1,11 +1,8 @@
1
1
  from datetime import datetime
2
2
 
3
- import pytest
4
3
  from flask import url_for
5
4
 
6
5
  from udata.core.dataset.factories import DatasetFactory
7
- from udata.core.topic.factories import TopicFactory
8
- from udata.search import reindex
9
6
  from udata.tests.api import APITestCase
10
7
  from udata.tests.helpers import assert_status
11
8
 
udata/tests/test_owned.py CHANGED
@@ -161,8 +161,8 @@ class OwnedQuerysetTest(DBTestMixin, TestCase):
161
161
  result = Owned.objects.owned_by(org, user)
162
162
 
163
163
  self.assertEqual(len(result), 2)
164
- for owned in result:
165
- self.assertIn(owned, owneds)
164
+ for owned_ in result:
165
+ self.assertIn(owned_, owneds)
166
166
 
167
- for owned in excluded:
168
- self.assertNotIn(owned, result)
167
+ for owned_ in excluded:
168
+ self.assertNotIn(owned_, result)
@@ -273,7 +273,7 @@ class SlugAsSLugFieldWithFollowTest(AsSlugMixin):
273
273
  assert404(client.get(second_url))
274
274
  assert404(client.get(last_url))
275
275
 
276
- assert SlugFollow.objects.count() is 0
276
+ assert SlugFollow.objects.count() == 0
277
277
 
278
278
 
279
279
  @pytest.mark.usefixtures("clean_db")