udata 9.1.2.dev30355__py2.py3-none-any.whl → 9.1.2.dev30382__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of udata might be problematic. Click here for more details.

Files changed (425) hide show
  1. tasks/__init__.py +109 -107
  2. tasks/helpers.py +18 -18
  3. udata/__init__.py +4 -4
  4. udata/admin/views.py +5 -5
  5. udata/api/__init__.py +135 -124
  6. udata/api/commands.py +45 -37
  7. udata/api/errors.py +5 -4
  8. udata/api/fields.py +23 -21
  9. udata/api/oauth2.py +55 -74
  10. udata/api/parsers.py +15 -15
  11. udata/api/signals.py +1 -1
  12. udata/api_fields.py +137 -89
  13. udata/app.py +56 -54
  14. udata/assets.py +5 -5
  15. udata/auth/__init__.py +37 -26
  16. udata/auth/forms.py +23 -15
  17. udata/auth/helpers.py +1 -1
  18. udata/auth/mails.py +3 -3
  19. udata/auth/password_validation.py +19 -15
  20. udata/auth/views.py +94 -68
  21. udata/commands/__init__.py +71 -69
  22. udata/commands/cache.py +7 -7
  23. udata/commands/db.py +201 -140
  24. udata/commands/dcat.py +36 -30
  25. udata/commands/fixtures.py +100 -84
  26. udata/commands/images.py +21 -20
  27. udata/commands/info.py +17 -20
  28. udata/commands/init.py +10 -10
  29. udata/commands/purge.py +12 -13
  30. udata/commands/serve.py +41 -29
  31. udata/commands/static.py +16 -18
  32. udata/commands/test.py +20 -20
  33. udata/commands/tests/fixtures.py +26 -24
  34. udata/commands/worker.py +31 -33
  35. udata/core/__init__.py +12 -12
  36. udata/core/activity/__init__.py +0 -1
  37. udata/core/activity/api.py +59 -49
  38. udata/core/activity/models.py +28 -26
  39. udata/core/activity/signals.py +1 -1
  40. udata/core/activity/tasks.py +16 -10
  41. udata/core/badges/api.py +6 -6
  42. udata/core/badges/commands.py +14 -13
  43. udata/core/badges/fields.py +8 -5
  44. udata/core/badges/forms.py +7 -4
  45. udata/core/badges/models.py +16 -31
  46. udata/core/badges/permissions.py +1 -3
  47. udata/core/badges/signals.py +2 -2
  48. udata/core/badges/tasks.py +3 -2
  49. udata/core/badges/tests/test_commands.py +10 -10
  50. udata/core/badges/tests/test_model.py +24 -31
  51. udata/core/contact_point/api.py +19 -18
  52. udata/core/contact_point/api_fields.py +21 -14
  53. udata/core/contact_point/factories.py +2 -2
  54. udata/core/contact_point/forms.py +7 -6
  55. udata/core/contact_point/models.py +3 -5
  56. udata/core/dataservices/api.py +26 -21
  57. udata/core/dataservices/factories.py +13 -11
  58. udata/core/dataservices/models.py +35 -40
  59. udata/core/dataservices/permissions.py +4 -4
  60. udata/core/dataservices/rdf.py +40 -17
  61. udata/core/dataservices/tasks.py +4 -3
  62. udata/core/dataset/actions.py +10 -10
  63. udata/core/dataset/activities.py +21 -23
  64. udata/core/dataset/api.py +321 -298
  65. udata/core/dataset/api_fields.py +443 -271
  66. udata/core/dataset/apiv2.py +305 -229
  67. udata/core/dataset/commands.py +38 -36
  68. udata/core/dataset/constants.py +61 -54
  69. udata/core/dataset/csv.py +70 -74
  70. udata/core/dataset/events.py +39 -32
  71. udata/core/dataset/exceptions.py +8 -4
  72. udata/core/dataset/factories.py +57 -65
  73. udata/core/dataset/forms.py +87 -63
  74. udata/core/dataset/models.py +336 -280
  75. udata/core/dataset/permissions.py +9 -6
  76. udata/core/dataset/preview.py +15 -17
  77. udata/core/dataset/rdf.py +156 -122
  78. udata/core/dataset/search.py +92 -77
  79. udata/core/dataset/signals.py +1 -1
  80. udata/core/dataset/tasks.py +63 -54
  81. udata/core/discussions/actions.py +5 -5
  82. udata/core/discussions/api.py +124 -120
  83. udata/core/discussions/factories.py +2 -2
  84. udata/core/discussions/forms.py +9 -7
  85. udata/core/discussions/metrics.py +1 -3
  86. udata/core/discussions/models.py +25 -24
  87. udata/core/discussions/notifications.py +18 -14
  88. udata/core/discussions/permissions.py +3 -3
  89. udata/core/discussions/signals.py +4 -4
  90. udata/core/discussions/tasks.py +24 -28
  91. udata/core/followers/api.py +32 -33
  92. udata/core/followers/models.py +9 -9
  93. udata/core/followers/signals.py +3 -3
  94. udata/core/jobs/actions.py +7 -7
  95. udata/core/jobs/api.py +99 -92
  96. udata/core/jobs/commands.py +48 -49
  97. udata/core/jobs/forms.py +11 -11
  98. udata/core/jobs/models.py +6 -6
  99. udata/core/metrics/__init__.py +2 -2
  100. udata/core/metrics/commands.py +34 -30
  101. udata/core/metrics/models.py +2 -4
  102. udata/core/metrics/signals.py +1 -1
  103. udata/core/metrics/tasks.py +3 -3
  104. udata/core/organization/activities.py +12 -15
  105. udata/core/organization/api.py +167 -174
  106. udata/core/organization/api_fields.py +183 -124
  107. udata/core/organization/apiv2.py +32 -32
  108. udata/core/organization/commands.py +20 -22
  109. udata/core/organization/constants.py +11 -11
  110. udata/core/organization/csv.py +17 -15
  111. udata/core/organization/factories.py +8 -11
  112. udata/core/organization/forms.py +32 -26
  113. udata/core/organization/metrics.py +2 -1
  114. udata/core/organization/models.py +87 -67
  115. udata/core/organization/notifications.py +18 -14
  116. udata/core/organization/permissions.py +10 -11
  117. udata/core/organization/rdf.py +14 -14
  118. udata/core/organization/search.py +30 -28
  119. udata/core/organization/signals.py +7 -7
  120. udata/core/organization/tasks.py +42 -61
  121. udata/core/owned.py +38 -27
  122. udata/core/post/api.py +82 -81
  123. udata/core/post/constants.py +8 -5
  124. udata/core/post/factories.py +4 -4
  125. udata/core/post/forms.py +13 -14
  126. udata/core/post/models.py +20 -22
  127. udata/core/post/tests/test_api.py +30 -32
  128. udata/core/reports/api.py +8 -7
  129. udata/core/reports/constants.py +1 -3
  130. udata/core/reports/models.py +10 -10
  131. udata/core/reuse/activities.py +15 -19
  132. udata/core/reuse/api.py +123 -126
  133. udata/core/reuse/api_fields.py +120 -85
  134. udata/core/reuse/apiv2.py +11 -10
  135. udata/core/reuse/constants.py +23 -23
  136. udata/core/reuse/csv.py +18 -18
  137. udata/core/reuse/factories.py +5 -9
  138. udata/core/reuse/forms.py +24 -21
  139. udata/core/reuse/models.py +55 -51
  140. udata/core/reuse/permissions.py +2 -2
  141. udata/core/reuse/search.py +49 -46
  142. udata/core/reuse/signals.py +1 -1
  143. udata/core/reuse/tasks.py +4 -5
  144. udata/core/site/api.py +47 -50
  145. udata/core/site/factories.py +2 -2
  146. udata/core/site/forms.py +4 -5
  147. udata/core/site/models.py +94 -63
  148. udata/core/site/rdf.py +14 -14
  149. udata/core/spam/api.py +16 -9
  150. udata/core/spam/constants.py +4 -4
  151. udata/core/spam/fields.py +13 -7
  152. udata/core/spam/models.py +27 -20
  153. udata/core/spam/signals.py +1 -1
  154. udata/core/spam/tests/test_spam.py +6 -5
  155. udata/core/spatial/api.py +72 -80
  156. udata/core/spatial/api_fields.py +73 -58
  157. udata/core/spatial/commands.py +67 -64
  158. udata/core/spatial/constants.py +3 -3
  159. udata/core/spatial/factories.py +37 -54
  160. udata/core/spatial/forms.py +27 -26
  161. udata/core/spatial/geoids.py +17 -17
  162. udata/core/spatial/models.py +43 -47
  163. udata/core/spatial/tasks.py +2 -1
  164. udata/core/spatial/tests/test_api.py +115 -130
  165. udata/core/spatial/tests/test_fields.py +74 -77
  166. udata/core/spatial/tests/test_geoid.py +22 -22
  167. udata/core/spatial/tests/test_models.py +5 -7
  168. udata/core/spatial/translations.py +16 -16
  169. udata/core/storages/__init__.py +16 -18
  170. udata/core/storages/api.py +66 -64
  171. udata/core/storages/tasks.py +7 -7
  172. udata/core/storages/utils.py +15 -15
  173. udata/core/storages/views.py +5 -6
  174. udata/core/tags/api.py +17 -14
  175. udata/core/tags/csv.py +4 -4
  176. udata/core/tags/models.py +8 -5
  177. udata/core/tags/tasks.py +11 -13
  178. udata/core/tags/views.py +4 -4
  179. udata/core/topic/api.py +84 -73
  180. udata/core/topic/apiv2.py +157 -127
  181. udata/core/topic/factories.py +3 -4
  182. udata/core/topic/forms.py +12 -14
  183. udata/core/topic/models.py +14 -19
  184. udata/core/topic/parsers.py +26 -26
  185. udata/core/user/activities.py +30 -29
  186. udata/core/user/api.py +151 -152
  187. udata/core/user/api_fields.py +132 -100
  188. udata/core/user/apiv2.py +7 -7
  189. udata/core/user/commands.py +38 -38
  190. udata/core/user/factories.py +8 -9
  191. udata/core/user/forms.py +14 -11
  192. udata/core/user/metrics.py +2 -2
  193. udata/core/user/models.py +68 -69
  194. udata/core/user/permissions.py +4 -5
  195. udata/core/user/rdf.py +7 -8
  196. udata/core/user/tasks.py +2 -2
  197. udata/core/user/tests/test_user_model.py +24 -16
  198. udata/db/tasks.py +2 -1
  199. udata/entrypoints.py +35 -31
  200. udata/errors.py +2 -1
  201. udata/event/values.py +6 -6
  202. udata/factories.py +2 -2
  203. udata/features/identicon/api.py +5 -6
  204. udata/features/identicon/backends.py +48 -55
  205. udata/features/identicon/tests/test_backends.py +4 -5
  206. udata/features/notifications/__init__.py +0 -1
  207. udata/features/notifications/actions.py +9 -9
  208. udata/features/notifications/api.py +17 -13
  209. udata/features/territories/__init__.py +12 -10
  210. udata/features/territories/api.py +14 -15
  211. udata/features/territories/models.py +23 -28
  212. udata/features/transfer/actions.py +8 -11
  213. udata/features/transfer/api.py +84 -77
  214. udata/features/transfer/factories.py +2 -1
  215. udata/features/transfer/models.py +11 -12
  216. udata/features/transfer/notifications.py +19 -15
  217. udata/features/transfer/permissions.py +5 -5
  218. udata/forms/__init__.py +5 -2
  219. udata/forms/fields.py +164 -172
  220. udata/forms/validators.py +19 -22
  221. udata/forms/widgets.py +9 -13
  222. udata/frontend/__init__.py +31 -26
  223. udata/frontend/csv.py +68 -58
  224. udata/frontend/markdown.py +40 -44
  225. udata/harvest/actions.py +89 -77
  226. udata/harvest/api.py +294 -238
  227. udata/harvest/backends/__init__.py +4 -4
  228. udata/harvest/backends/base.py +128 -111
  229. udata/harvest/backends/dcat.py +80 -66
  230. udata/harvest/commands.py +56 -60
  231. udata/harvest/csv.py +8 -8
  232. udata/harvest/exceptions.py +6 -3
  233. udata/harvest/filters.py +24 -23
  234. udata/harvest/forms.py +27 -28
  235. udata/harvest/models.py +88 -80
  236. udata/harvest/notifications.py +15 -10
  237. udata/harvest/signals.py +13 -13
  238. udata/harvest/tasks.py +11 -10
  239. udata/harvest/tests/factories.py +23 -24
  240. udata/harvest/tests/test_actions.py +136 -166
  241. udata/harvest/tests/test_api.py +220 -214
  242. udata/harvest/tests/test_base_backend.py +117 -112
  243. udata/harvest/tests/test_dcat_backend.py +380 -308
  244. udata/harvest/tests/test_filters.py +33 -22
  245. udata/harvest/tests/test_models.py +11 -14
  246. udata/harvest/tests/test_notifications.py +6 -7
  247. udata/harvest/tests/test_tasks.py +7 -6
  248. udata/i18n.py +237 -78
  249. udata/linkchecker/backends.py +5 -11
  250. udata/linkchecker/checker.py +23 -22
  251. udata/linkchecker/commands.py +4 -6
  252. udata/linkchecker/models.py +6 -6
  253. udata/linkchecker/tasks.py +18 -20
  254. udata/mail.py +21 -21
  255. udata/migrations/2020-07-24-remove-s-from-scope-oauth.py +9 -8
  256. udata/migrations/2020-08-24-add-fs-filename.py +9 -8
  257. udata/migrations/2020-09-28-update-reuses-datasets-metrics.py +5 -4
  258. udata/migrations/2020-10-16-migrate-ods-resources.py +9 -10
  259. udata/migrations/2021-04-08-update-schema-with-new-structure.py +8 -7
  260. udata/migrations/2021-05-27-fix-default-schema-name.py +7 -6
  261. udata/migrations/2021-07-05-remove-unused-badges.py +17 -15
  262. udata/migrations/2021-07-07-update-schema-for-community-resources.py +7 -6
  263. udata/migrations/2021-08-17-follow-integrity.py +5 -4
  264. udata/migrations/2021-08-17-harvest-integrity.py +13 -12
  265. udata/migrations/2021-08-17-oauth2client-integrity.py +5 -4
  266. udata/migrations/2021-08-17-transfer-integrity.py +5 -4
  267. udata/migrations/2021-08-17-users-integrity.py +9 -8
  268. udata/migrations/2021-12-14-reuse-topics.py +7 -6
  269. udata/migrations/2022-04-21-improve-extension-detection.py +8 -7
  270. udata/migrations/2022-09-22-clean-inactive-harvest-datasets.py +16 -14
  271. udata/migrations/2022-10-10-add-fs_uniquifier-to-user-model.py +6 -6
  272. udata/migrations/2022-10-10-migrate-harvest-extras.py +36 -26
  273. udata/migrations/2023-02-08-rename-internal-dates.py +46 -28
  274. udata/migrations/2024-01-29-fix-reuse-and-dataset-with-private-None.py +10 -8
  275. udata/migrations/2024-03-22-migrate-activity-kwargs-to-extras.py +6 -4
  276. udata/migrations/2024-06-11-fix-reuse-datasets-references.py +7 -6
  277. udata/migrations/__init__.py +123 -105
  278. udata/models/__init__.py +4 -4
  279. udata/mongo/__init__.py +13 -11
  280. udata/mongo/badges_field.py +3 -2
  281. udata/mongo/datetime_fields.py +13 -12
  282. udata/mongo/document.py +17 -16
  283. udata/mongo/engine.py +15 -16
  284. udata/mongo/errors.py +2 -1
  285. udata/mongo/extras_fields.py +30 -20
  286. udata/mongo/queryset.py +12 -12
  287. udata/mongo/slug_fields.py +38 -28
  288. udata/mongo/taglist_field.py +1 -2
  289. udata/mongo/url_field.py +5 -5
  290. udata/mongo/uuid_fields.py +4 -3
  291. udata/notifications/__init__.py +1 -1
  292. udata/notifications/mattermost.py +10 -9
  293. udata/rdf.py +167 -188
  294. udata/routing.py +40 -45
  295. udata/search/__init__.py +18 -19
  296. udata/search/adapter.py +17 -16
  297. udata/search/commands.py +44 -51
  298. udata/search/fields.py +13 -20
  299. udata/search/query.py +23 -18
  300. udata/search/result.py +9 -10
  301. udata/sentry.py +21 -19
  302. udata/settings.py +262 -198
  303. udata/sitemap.py +8 -6
  304. udata/static/chunks/{11.e9b9ca1f3e03d4020377.js → 11.52e531c19f8de80c00cf.js} +3 -3
  305. udata/static/chunks/{11.e9b9ca1f3e03d4020377.js.map → 11.52e531c19f8de80c00cf.js.map} +1 -1
  306. udata/static/chunks/{13.038c0d9aa0dfa0181c4b.js → 13.c3343a7f1070061c0e10.js} +2 -2
  307. udata/static/chunks/{13.038c0d9aa0dfa0181c4b.js.map → 13.c3343a7f1070061c0e10.js.map} +1 -1
  308. udata/static/chunks/{16.0baa2b64a74a2dcde25c.js → 16.8fa42440ad75ca172e6d.js} +2 -2
  309. udata/static/chunks/{16.0baa2b64a74a2dcde25c.js.map → 16.8fa42440ad75ca172e6d.js.map} +1 -1
  310. udata/static/chunks/{19.350a9f150b074b4ecefa.js → 19.9c6c8412729cd6d59cfa.js} +3 -3
  311. udata/static/chunks/{19.350a9f150b074b4ecefa.js.map → 19.9c6c8412729cd6d59cfa.js.map} +1 -1
  312. udata/static/chunks/{5.6ebbce2b9b3e696d3da5.js → 5.71d15c2e4f21feee2a9a.js} +3 -3
  313. udata/static/chunks/{5.6ebbce2b9b3e696d3da5.js.map → 5.71d15c2e4f21feee2a9a.js.map} +1 -1
  314. udata/static/chunks/{6.d8a5f7b017bcbd083641.js → 6.9139dc098b8ea640b890.js} +3 -3
  315. udata/static/chunks/{6.d8a5f7b017bcbd083641.js.map → 6.9139dc098b8ea640b890.js.map} +1 -1
  316. udata/static/common.js +1 -1
  317. udata/static/common.js.map +1 -1
  318. udata/storage/s3.py +20 -13
  319. udata/tags.py +4 -5
  320. udata/tasks.py +43 -42
  321. udata/tests/__init__.py +9 -6
  322. udata/tests/api/__init__.py +5 -6
  323. udata/tests/api/test_auth_api.py +395 -321
  324. udata/tests/api/test_base_api.py +31 -33
  325. udata/tests/api/test_contact_points.py +7 -9
  326. udata/tests/api/test_dataservices_api.py +211 -158
  327. udata/tests/api/test_datasets_api.py +823 -812
  328. udata/tests/api/test_follow_api.py +13 -15
  329. udata/tests/api/test_me_api.py +95 -112
  330. udata/tests/api/test_organizations_api.py +301 -339
  331. udata/tests/api/test_reports_api.py +35 -25
  332. udata/tests/api/test_reuses_api.py +134 -139
  333. udata/tests/api/test_swagger.py +5 -5
  334. udata/tests/api/test_tags_api.py +18 -25
  335. udata/tests/api/test_topics_api.py +94 -94
  336. udata/tests/api/test_transfer_api.py +53 -48
  337. udata/tests/api/test_user_api.py +128 -141
  338. udata/tests/apiv2/test_datasets.py +290 -198
  339. udata/tests/apiv2/test_me_api.py +10 -11
  340. udata/tests/apiv2/test_organizations.py +56 -74
  341. udata/tests/apiv2/test_swagger.py +5 -5
  342. udata/tests/apiv2/test_topics.py +69 -87
  343. udata/tests/cli/test_cli_base.py +8 -8
  344. udata/tests/cli/test_db_cli.py +21 -19
  345. udata/tests/dataservice/test_dataservice_tasks.py +8 -12
  346. udata/tests/dataset/test_csv_adapter.py +44 -35
  347. udata/tests/dataset/test_dataset_actions.py +2 -3
  348. udata/tests/dataset/test_dataset_commands.py +7 -8
  349. udata/tests/dataset/test_dataset_events.py +36 -29
  350. udata/tests/dataset/test_dataset_model.py +224 -217
  351. udata/tests/dataset/test_dataset_rdf.py +142 -131
  352. udata/tests/dataset/test_dataset_tasks.py +15 -15
  353. udata/tests/dataset/test_resource_preview.py +10 -13
  354. udata/tests/features/territories/__init__.py +9 -13
  355. udata/tests/features/territories/test_territories_api.py +71 -91
  356. udata/tests/forms/test_basic_fields.py +7 -7
  357. udata/tests/forms/test_current_user_field.py +39 -66
  358. udata/tests/forms/test_daterange_field.py +31 -39
  359. udata/tests/forms/test_dict_field.py +28 -26
  360. udata/tests/forms/test_extras_fields.py +102 -76
  361. udata/tests/forms/test_form_field.py +8 -8
  362. udata/tests/forms/test_image_field.py +33 -26
  363. udata/tests/forms/test_model_field.py +134 -123
  364. udata/tests/forms/test_model_list_field.py +7 -7
  365. udata/tests/forms/test_nested_model_list_field.py +117 -79
  366. udata/tests/forms/test_publish_as_field.py +36 -65
  367. udata/tests/forms/test_reference_field.py +34 -53
  368. udata/tests/forms/test_user_forms.py +23 -21
  369. udata/tests/forms/test_uuid_field.py +6 -10
  370. udata/tests/frontend/__init__.py +9 -6
  371. udata/tests/frontend/test_auth.py +7 -6
  372. udata/tests/frontend/test_csv.py +81 -96
  373. udata/tests/frontend/test_hooks.py +43 -43
  374. udata/tests/frontend/test_markdown.py +211 -191
  375. udata/tests/helpers.py +32 -37
  376. udata/tests/models.py +2 -2
  377. udata/tests/organization/test_csv_adapter.py +21 -16
  378. udata/tests/organization/test_notifications.py +11 -18
  379. udata/tests/organization/test_organization_model.py +13 -13
  380. udata/tests/organization/test_organization_rdf.py +29 -22
  381. udata/tests/organization/test_organization_tasks.py +16 -17
  382. udata/tests/plugin.py +76 -73
  383. udata/tests/reuse/test_reuse_model.py +21 -21
  384. udata/tests/reuse/test_reuse_task.py +11 -13
  385. udata/tests/search/__init__.py +11 -12
  386. udata/tests/search/test_adapter.py +60 -70
  387. udata/tests/search/test_query.py +16 -16
  388. udata/tests/search/test_results.py +10 -7
  389. udata/tests/site/test_site_api.py +11 -16
  390. udata/tests/site/test_site_metrics.py +20 -30
  391. udata/tests/site/test_site_model.py +4 -5
  392. udata/tests/site/test_site_rdf.py +94 -78
  393. udata/tests/test_activity.py +17 -17
  394. udata/tests/test_discussions.py +292 -299
  395. udata/tests/test_i18n.py +37 -40
  396. udata/tests/test_linkchecker.py +91 -85
  397. udata/tests/test_mail.py +13 -17
  398. udata/tests/test_migrations.py +219 -180
  399. udata/tests/test_model.py +164 -157
  400. udata/tests/test_notifications.py +17 -17
  401. udata/tests/test_owned.py +14 -14
  402. udata/tests/test_rdf.py +25 -23
  403. udata/tests/test_routing.py +89 -93
  404. udata/tests/test_storages.py +137 -128
  405. udata/tests/test_tags.py +44 -46
  406. udata/tests/test_topics.py +7 -7
  407. udata/tests/test_transfer.py +42 -49
  408. udata/tests/test_uris.py +160 -161
  409. udata/tests/test_utils.py +79 -71
  410. udata/tests/user/test_user_rdf.py +5 -9
  411. udata/tests/workers/test_jobs_commands.py +57 -58
  412. udata/tests/workers/test_tasks_routing.py +23 -29
  413. udata/tests/workers/test_workers_api.py +125 -131
  414. udata/tests/workers/test_workers_helpers.py +6 -6
  415. udata/tracking.py +4 -6
  416. udata/uris.py +45 -46
  417. udata/utils.py +68 -66
  418. udata/wsgi.py +1 -1
  419. {udata-9.1.2.dev30355.dist-info → udata-9.1.2.dev30382.dist-info}/METADATA +3 -2
  420. udata-9.1.2.dev30382.dist-info/RECORD +704 -0
  421. udata-9.1.2.dev30355.dist-info/RECORD +0 -704
  422. {udata-9.1.2.dev30355.dist-info → udata-9.1.2.dev30382.dist-info}/LICENSE +0 -0
  423. {udata-9.1.2.dev30355.dist-info → udata-9.1.2.dev30382.dist-info}/WHEEL +0 -0
  424. {udata-9.1.2.dev30355.dist-info → udata-9.1.2.dev30382.dist-info}/entry_points.txt +0 -0
  425. {udata-9.1.2.dev30355.dist-info → udata-9.1.2.dev30382.dist-info}/top_level.txt +0 -0
@@ -3,8 +3,8 @@ from flask import url_for
3
3
  from udata.core import storages
4
4
  from udata.core.user.factories import AdminFactory, UserFactory
5
5
  from udata.models import Follow
6
- from udata.utils import faker
7
6
  from udata.tests.helpers import capture_mails, create_test_image
7
+ from udata.utils import faker
8
8
 
9
9
  from . import APITestCase
10
10
 
@@ -13,47 +13,46 @@ class UserAPITest(APITestCase):
13
13
  modules = []
14
14
 
15
15
  def test_follow_user(self):
16
- '''It should follow an user on POST'''
16
+ """It should follow an user on POST"""
17
17
  user = self.login()
18
18
  to_follow = UserFactory()
19
19
 
20
- response = self.post(url_for('api.user_followers', id=to_follow.id))
20
+ response = self.post(url_for("api.user_followers", id=to_follow.id))
21
21
  self.assert201(response)
22
22
 
23
23
  to_follow.count_followers()
24
- self.assertEqual(to_follow.get_metrics()['followers'], 1)
24
+ self.assertEqual(to_follow.get_metrics()["followers"], 1)
25
25
 
26
26
  nb_followers = Follow.objects.followers(to_follow).count()
27
27
 
28
- self.assertEqual(response.json['followers'], nb_followers)
28
+ self.assertEqual(response.json["followers"], nb_followers)
29
29
  self.assertEqual(Follow.objects.following(to_follow).count(), 0)
30
30
  self.assertEqual(nb_followers, 1)
31
- self.assertIsInstance(Follow.objects.followers(to_follow).first(),
32
- Follow)
31
+ self.assertIsInstance(Follow.objects.followers(to_follow).first(), Follow)
33
32
  self.assertEqual(Follow.objects.following(user).count(), 1)
34
33
  self.assertEqual(Follow.objects.followers(user).count(), 0)
35
34
 
36
35
  def test_follow_myself(self):
37
- '''It should not allow to follow myself'''
36
+ """It should not allow to follow myself"""
38
37
  user = self.login()
39
38
 
40
- response = self.post(url_for('api.user_followers', id=user.id))
39
+ response = self.post(url_for("api.user_followers", id=user.id))
41
40
  self.assertStatus(response, 403)
42
41
 
43
42
  self.assertEqual(Follow.objects.followers(user).count(), 0)
44
43
 
45
44
  def test_unfollow(self):
46
- '''It should unfollow the user on DELETE'''
45
+ """It should unfollow the user on DELETE"""
47
46
  user = self.login()
48
47
  to_follow = UserFactory()
49
48
  Follow.objects.create(follower=user, following=to_follow)
50
49
 
51
- response = self.delete(url_for('api.user_followers', id=to_follow.id))
50
+ response = self.delete(url_for("api.user_followers", id=to_follow.id))
52
51
  self.assert200(response)
53
52
 
54
53
  nb_followers = Follow.objects.followers(to_follow).count()
55
54
 
56
- self.assertEqual(response.json['followers'], nb_followers)
55
+ self.assertEqual(response.json["followers"], nb_followers)
57
56
 
58
57
  self.assertEqual(Follow.objects.following(to_follow).count(), 0)
59
58
  self.assertEqual(nb_followers, 0)
@@ -61,288 +60,277 @@ class UserAPITest(APITestCase):
61
60
  self.assertEqual(Follow.objects.followers(user).count(), 0)
62
61
 
63
62
  def test_suggest_users_api_first_name(self):
64
- '''It should suggest users based on first name'''
63
+ """It should suggest users based on first name"""
65
64
  for i in range(4):
66
- UserFactory(
67
- first_name='first-name-test-{0}'.format(i) if i % 2 else faker.word())
65
+ UserFactory(first_name="first-name-test-{0}".format(i) if i % 2 else faker.word())
68
66
 
69
- response = self.get(url_for('api.suggest_users'),
70
- qs={'q': 'first-name-test', 'size': '5'})
67
+ response = self.get(url_for("api.suggest_users"), qs={"q": "first-name-test", "size": "5"})
71
68
  self.assert200(response)
72
69
 
73
70
  self.assertLessEqual(len(response.json), 5)
74
71
  self.assertGreater(len(response.json), 1)
75
72
 
76
73
  for suggestion in response.json:
77
- self.assertIn('id', suggestion)
78
- self.assertIn('first_name', suggestion)
79
- self.assertIn('last_name', suggestion)
80
- self.assertIn('avatar_url', suggestion)
81
- self.assertIn('slug', suggestion)
82
- self.assertIn('first-name-test', suggestion['first_name'])
74
+ self.assertIn("id", suggestion)
75
+ self.assertIn("first_name", suggestion)
76
+ self.assertIn("last_name", suggestion)
77
+ self.assertIn("avatar_url", suggestion)
78
+ self.assertIn("slug", suggestion)
79
+ self.assertIn("first-name-test", suggestion["first_name"])
83
80
 
84
81
  def test_suggest_users_api_last_name(self):
85
- '''It should suggest users based on last name'''
82
+ """It should suggest users based on last name"""
86
83
  for i in range(4):
87
- UserFactory(
88
- last_name='last-name-test-{0}'.format(i) if i % 2 else faker.word())
84
+ UserFactory(last_name="last-name-test-{0}".format(i) if i % 2 else faker.word())
89
85
 
90
- response = self.get(url_for('api.suggest_users'),
91
- qs={'q': 'last-name-test', 'size': '5'})
86
+ response = self.get(url_for("api.suggest_users"), qs={"q": "last-name-test", "size": "5"})
92
87
  self.assert200(response)
93
88
 
94
89
  self.assertLessEqual(len(response.json), 5)
95
90
  self.assertGreater(len(response.json), 1)
96
91
 
97
92
  for suggestion in response.json:
98
- self.assertIn('id', suggestion)
99
- self.assertIn('first_name', suggestion)
100
- self.assertIn('last_name', suggestion)
101
- self.assertIn('avatar_url', suggestion)
102
- self.assertIn('last-name-test', suggestion['last_name'])
93
+ self.assertIn("id", suggestion)
94
+ self.assertIn("first_name", suggestion)
95
+ self.assertIn("last_name", suggestion)
96
+ self.assertIn("avatar_url", suggestion)
97
+ self.assertIn("last-name-test", suggestion["last_name"])
103
98
 
104
99
  def test_suggest_users_api_unicode(self):
105
- '''It should suggest users with special characters'''
100
+ """It should suggest users with special characters"""
106
101
  for i in range(4):
107
- UserFactory(
108
- last_name='last-name-testé-{0}'.format(i) if i % 2 else faker.word())
102
+ UserFactory(last_name="last-name-testé-{0}".format(i) if i % 2 else faker.word())
109
103
 
110
- response = self.get(url_for('api.suggest_users'),
111
- qs={'q': 'last-name-testé', 'size': '5'})
104
+ response = self.get(url_for("api.suggest_users"), qs={"q": "last-name-testé", "size": "5"})
112
105
  self.assert200(response)
113
106
 
114
107
  self.assertLessEqual(len(response.json), 5)
115
108
  self.assertGreater(len(response.json), 1)
116
109
 
117
110
  for suggestion in response.json:
118
- self.assertIn('id', suggestion)
119
- self.assertIn('first_name', suggestion)
120
- self.assertIn('last_name', suggestion)
121
- self.assertIn('avatar_url', suggestion)
122
- self.assertIn('last-name-testé', suggestion['last_name'])
111
+ self.assertIn("id", suggestion)
112
+ self.assertIn("first_name", suggestion)
113
+ self.assertIn("last_name", suggestion)
114
+ self.assertIn("avatar_url", suggestion)
115
+ self.assertIn("last-name-testé", suggestion["last_name"])
123
116
 
124
117
  def test_suggest_users_api_no_match(self):
125
- '''It should not provide user suggestion if no match'''
118
+ """It should not provide user suggestion if no match"""
126
119
  UserFactory.create_batch(3)
127
120
 
128
- response = self.get(url_for('api.suggest_users'),
129
- qs={'q': 'xxxxxx', 'size': '5'})
121
+ response = self.get(url_for("api.suggest_users"), qs={"q": "xxxxxx", "size": "5"})
130
122
  self.assert200(response)
131
123
  self.assertEqual(len(response.json), 0)
132
124
 
133
125
  def test_suggest_users_api_empty(self):
134
- '''It should not provide user suggestion if no data'''
135
- response = self.get(url_for('api.suggest_users'),
136
- qs={'q': 'xxxxxx', 'size': '5'})
126
+ """It should not provide user suggestion if no data"""
127
+ response = self.get(url_for("api.suggest_users"), qs={"q": "xxxxxx", "size": "5"})
137
128
  self.assert200(response)
138
129
  self.assertEqual(len(response.json), 0)
139
130
 
140
131
  def test_suggest_users_api_no_dedup(self):
141
- '''It should suggest users without deduplicating homonyms'''
142
- UserFactory.create_batch(2, first_name='test', last_name='homonym')
132
+ """It should suggest users without deduplicating homonyms"""
133
+ UserFactory.create_batch(2, first_name="test", last_name="homonym")
143
134
 
144
- response = self.get(url_for('api.suggest_users'),
145
- qs={'q': 'homonym', 'size': '5'})
135
+ response = self.get(url_for("api.suggest_users"), qs={"q": "homonym", "size": "5"})
146
136
  self.assert200(response)
147
137
 
148
138
  self.assertEqual(len(response.json), 2)
149
139
 
150
140
  for suggestion in response.json:
151
- self.assertEqual(suggestion['first_name'], 'test')
152
- self.assertEqual(suggestion['last_name'], 'homonym')
141
+ self.assertEqual(suggestion["first_name"], "test")
142
+ self.assertEqual(suggestion["last_name"], "homonym")
153
143
 
154
144
  def test_user_api_full_text_search_first_name(self):
155
- '''It should find users based on first name'''
145
+ """It should find users based on first name"""
156
146
  self.login(AdminFactory())
157
147
 
158
148
  for i in range(4):
159
- UserFactory(
160
- first_name='test-{0}'.format(i) if i % 2 else faker.word())
149
+ UserFactory(first_name="test-{0}".format(i) if i % 2 else faker.word())
161
150
 
162
- response = self.get(url_for('api.users', q='test'))
151
+ response = self.get(url_for("api.users", q="test"))
163
152
  self.assert200(response)
164
153
 
165
- self.assertEqual(len(response.json['data']), 2)
154
+ self.assertEqual(len(response.json["data"]), 2)
166
155
 
167
156
  def test_user_api_full_text_search_last_name(self):
168
- '''It should find users based on last name'''
157
+ """It should find users based on last name"""
169
158
  self.login(AdminFactory())
170
159
 
171
160
  for i in range(4):
172
- UserFactory(
173
- last_name='test-{0}'.format(i) if i % 2 else faker.word())
161
+ UserFactory(last_name="test-{0}".format(i) if i % 2 else faker.word())
174
162
 
175
- response = self.get(url_for('api.users', q='test'))
163
+ response = self.get(url_for("api.users", q="test"))
176
164
  self.assert200(response)
177
165
 
178
- self.assertEqual(len(response.json['data']), 2)
166
+ self.assertEqual(len(response.json["data"]), 2)
179
167
 
180
168
  def test_user_api_full_text_search_unicode(self):
181
- '''It should find user with special characters'''
169
+ """It should find user with special characters"""
182
170
  self.login(AdminFactory())
183
171
 
184
172
  for i in range(4):
185
- UserFactory(
186
- first_name='test-{0}'.format(i) if i % 2 else faker.word())
173
+ UserFactory(first_name="test-{0}".format(i) if i % 2 else faker.word())
187
174
 
188
- user = UserFactory(first_name='test', last_name='testé')
175
+ user = UserFactory(first_name="test", last_name="testé")
189
176
 
190
- response = self.get(url_for('api.users', q='test testé'))
177
+ response = self.get(url_for("api.users", q="test testé"))
191
178
  self.assert200(response)
192
179
 
193
- self.assertEqual(len(response.json['data']), 3)
194
- self.assertEqual(response.json['data'][0]['id'], str(user.id))
180
+ self.assertEqual(len(response.json["data"]), 3)
181
+ self.assertEqual(response.json["data"][0]["id"], str(user.id))
195
182
 
196
183
  def test_find_users_api_no_match(self):
197
- '''It should not find user if no match'''
184
+ """It should not find user if no match"""
198
185
  self.login(AdminFactory())
199
186
  UserFactory.create_batch(3)
200
187
 
201
- response = self.get(url_for('api.users', q='xxxxxx'))
188
+ response = self.get(url_for("api.users", q="xxxxxx"))
202
189
  self.assert200(response)
203
- self.assertEqual(len(response.json['data']), 0)
190
+ self.assertEqual(len(response.json["data"]), 0)
204
191
 
205
192
  def test_users_as_admin(self):
206
- '''It should provide a list of users'''
193
+ """It should provide a list of users"""
207
194
  self.login(AdminFactory(email="thibaud@example.org"))
208
195
 
209
196
  user = UserFactory(
210
197
  about=faker.paragraph(),
211
198
  website=faker.url(),
212
199
  avatar_url=faker.url(),
213
- metrics={'datasets': 10, 'followers': 1, 'following': 0, 'reuses': 2})
214
- response = self.get(url_for('api.users'))
200
+ metrics={"datasets": 10, "followers": 1, "following": 0, "reuses": 2},
201
+ )
202
+ response = self.get(url_for("api.users"))
215
203
  self.assert200(response)
216
- users = response.json['data']
217
- self.assertEqual(users[1]['email'], "thibaud@example.org") # Admin user created for login
218
- self.assertEqual(users[0]['id'], str(user.id))
219
- self.assertEqual(users[0]['slug'], user.slug)
220
- self.assertEqual(users[0]['first_name'], user.first_name)
221
- self.assertEqual(users[0]['last_name'], user.last_name)
222
- self.assertEqual(users[0]['website'], user.website)
223
- self.assertEqual(users[0]['about'], user.about)
224
- self.assertEqual(users[0]['metrics'], user.metrics)
204
+ users = response.json["data"]
205
+ self.assertEqual(users[1]["email"], "thibaud@example.org") # Admin user created for login
206
+ self.assertEqual(users[0]["id"], str(user.id))
207
+ self.assertEqual(users[0]["slug"], user.slug)
208
+ self.assertEqual(users[0]["first_name"], user.first_name)
209
+ self.assertEqual(users[0]["last_name"], user.last_name)
210
+ self.assertEqual(users[0]["website"], user.website)
211
+ self.assertEqual(users[0]["about"], user.about)
212
+ self.assertEqual(users[0]["metrics"], user.metrics)
225
213
 
226
214
  def test_users_forbidden(self):
227
215
  UserFactory()
228
-
229
- response = self.get(url_for('api.users'))
216
+
217
+ response = self.get(url_for("api.users"))
230
218
  self.assert401(response)
231
219
 
232
220
  self.login()
233
- response = self.get(url_for('api.users'))
221
+ response = self.get(url_for("api.users"))
234
222
  self.assert403(response)
235
223
 
236
224
  def test_get_user(self):
237
- '''It should get a user'''
225
+ """It should get a user"""
238
226
  user = UserFactory()
239
- response = self.get(url_for('api.user', user=user))
227
+ response = self.get(url_for("api.user", user=user))
240
228
  self.assert200(response)
241
229
 
242
230
  def test_get_inactive_user(self):
243
- '''It should raise a 410'''
231
+ """It should raise a 410"""
244
232
  user = UserFactory(active=False)
245
- response = self.get(url_for('api.user', user=user))
233
+ response = self.get(url_for("api.user", user=user))
246
234
  self.assert410(response)
247
235
 
248
236
  def test_get_inactive_user_with_a_non_admin(self):
249
- '''It should raise a 410'''
237
+ """It should raise a 410"""
250
238
  user = UserFactory(active=False)
251
239
  self.login()
252
- response = self.get(url_for('api.user', user=user))
240
+ response = self.get(url_for("api.user", user=user))
253
241
  self.assert410(response)
254
242
 
255
243
  def test_change_avatar_user_with_a_non_admin(self):
256
- '''It should raise a 403'''
244
+ """It should raise a 403"""
257
245
  user = UserFactory(active=True)
258
246
  self.login()
259
- response = self.post(url_for('api.user_avatar', user=user))
247
+ response = self.post(url_for("api.user_avatar", user=user))
260
248
  self.assert403(response)
261
249
 
262
250
  def test_get_inactive_user_with_an_admin(self):
263
- '''It should get a user'''
251
+ """It should get a user"""
264
252
  user = UserFactory(active=False)
265
253
  self.login(AdminFactory())
266
- response = self.get(url_for('api.user', user=user))
254
+ response = self.get(url_for("api.user", user=user))
267
255
  self.assert200(response)
268
256
 
269
257
  def test_user_api_create_as_admin(self):
270
- '''It should create a user'''
258
+ """It should create a user"""
271
259
  self.login(AdminFactory())
272
260
  data = {
273
261
  "first_name": faker.first_name(),
274
262
  "last_name": faker.last_name(),
275
- "email": faker.email()
263
+ "email": faker.email(),
276
264
  }
277
- response = self.post(url_for('api.users'), data=data)
265
+ response = self.post(url_for("api.users"), data=data)
278
266
  self.assert201(response)
279
267
 
280
268
  def test_user_api_create_as_no_admin(self):
281
- '''It should not create a user'''
269
+ """It should not create a user"""
282
270
  self.login(UserFactory())
283
271
  data = {
284
272
  "first_name": faker.first_name(),
285
273
  "last_name": faker.last_name(),
286
- "email": faker.email()
274
+ "email": faker.email(),
287
275
  }
288
- response = self.post(url_for('api.users'), data=data)
276
+ response = self.post(url_for("api.users"), data=data)
289
277
  self.assert403(response)
290
278
 
291
279
  def test_user_api_update(self):
292
- '''It should update a user'''
280
+ """It should update a user"""
293
281
  self.login(AdminFactory())
294
282
  user = UserFactory()
295
283
  data = user.to_dict()
296
- data['active'] = False
297
- response = self.put(url_for('api.user', user=user), data)
284
+ data["active"] = False
285
+ response = self.put(url_for("api.user", user=user), data)
298
286
  self.assert200(response)
299
- self.assertFalse(response.json['active'])
287
+ self.assertFalse(response.json["active"])
300
288
 
301
289
  def test_user_api_update_with_website(self):
302
- '''It should raise a 400'''
290
+ """It should raise a 400"""
303
291
  self.login(AdminFactory())
304
292
  user = UserFactory()
305
293
  data = user.to_dict()
306
- data['website'] = 'foo'
307
- response = self.put(url_for('api.user', user=user), data)
294
+ data["website"] = "foo"
295
+ response = self.put(url_for("api.user", user=user), data)
308
296
  self.assert400(response)
309
- data['website'] = faker.url()
310
- response = self.put(url_for('api.user', user=user), data)
297
+ data["website"] = faker.url()
298
+ response = self.put(url_for("api.user", user=user), data)
311
299
  self.assert200(response)
312
300
 
313
301
  def test_user_api_update_with_a_non_admin_connected_user(self):
314
- '''It should raise a 403'''
302
+ """It should raise a 403"""
315
303
  user = UserFactory()
316
304
  self.login(user)
317
305
  data = user.to_dict()
318
- response = self.put(url_for('api.user', user=user), data)
306
+ response = self.put(url_for("api.user", user=user), data)
319
307
  self.assert403(response)
320
308
 
321
309
  def test_user_api_update_with_an_existing_role(self):
322
- '''It should update a user'''
310
+ """It should update a user"""
323
311
  self.login(AdminFactory())
324
312
  user = UserFactory()
325
313
  data = user.to_dict()
326
- data['roles'] = ['admin']
327
- response = self.put(url_for('api.user', user=user), data)
314
+ data["roles"] = ["admin"]
315
+ response = self.put(url_for("api.user", user=user), data)
328
316
  self.assert200(response)
329
- self.assertEqual(response.json['roles'], ['admin'])
317
+ self.assertEqual(response.json["roles"], ["admin"])
330
318
 
331
319
  def test_user_api_update_with_a_non_existing_role(self):
332
- '''It should raise a 400'''
320
+ """It should raise a 400"""
333
321
  self.login(AdminFactory())
334
322
  user = UserFactory()
335
323
  data = user.to_dict()
336
- data['roles'] = ['non_existing_role']
337
- response = self.put(url_for('api.user', user=user), data)
324
+ data["roles"] = ["non_existing_role"]
325
+ response = self.put(url_for("api.user", user=user), data)
338
326
  self.assert400(response)
339
327
 
340
328
  def test_user_roles(self):
341
- '''It should list the roles'''
329
+ """It should list the roles"""
342
330
  self.login(AdminFactory())
343
- response = self.get(url_for('api.user_roles'))
331
+ response = self.get(url_for("api.user_roles"))
344
332
  self.assert200(response)
345
- self.assertEqual(response.json, [{'name': 'admin'}])
333
+ self.assertEqual(response.json, [{"name": "admin"}])
346
334
 
347
335
  def test_delete_user(self):
348
336
  user = AdminFactory()
@@ -351,20 +339,20 @@ class UserAPITest(APITestCase):
351
339
  file = create_test_image()
352
340
 
353
341
  response = self.post(
354
- url_for('api.user_avatar', user=other_user),
355
- {'file': (file, 'test.png')},
342
+ url_for("api.user_avatar", user=other_user),
343
+ {"file": (file, "test.png")},
356
344
  json=False,
357
345
  )
358
346
  with capture_mails() as mails:
359
- response = self.delete(url_for('api.user', user=other_user))
347
+ response = self.delete(url_for("api.user", user=other_user))
360
348
  self.assertEqual(list(storages.avatars.list_files()), [])
361
349
  self.assert204(response)
362
350
  self.assertEquals(len(mails), 1)
363
351
 
364
352
  other_user.reload()
365
- response = self.delete(url_for('api.user', user=other_user))
353
+ response = self.delete(url_for("api.user", user=other_user))
366
354
  self.assert410(response)
367
- response = self.delete(url_for('api.user', user=user))
355
+ response = self.delete(url_for("api.user", user=user))
368
356
  self.assert403(response)
369
357
 
370
358
  def test_delete_user_without_notify(self):
@@ -373,26 +361,25 @@ class UserAPITest(APITestCase):
373
361
  other_user = UserFactory()
374
362
 
375
363
  with capture_mails() as mails:
376
- response = self.delete(url_for('api.user', user=other_user, no_mail=True))
364
+ response = self.delete(url_for("api.user", user=other_user, no_mail=True))
377
365
  self.assert204(response)
378
366
  self.assertEqual(len(mails), 0)
379
-
380
367
 
381
368
  def test_contact_points(self):
382
369
  user = AdminFactory()
383
370
  self.login(user)
384
371
  user = UserFactory()
385
372
  data = {
386
- 'email': 'mooneywayne@cobb-cochran.com',
387
- 'name': 'Martin Schultz',
388
- 'owner': str(user.id)
373
+ "email": "mooneywayne@cobb-cochran.com",
374
+ "name": "Martin Schultz",
375
+ "owner": str(user.id),
389
376
  }
390
377
 
391
- response = self.post(url_for('api.contact_points'), data)
378
+ response = self.post(url_for("api.contact_points"), data)
392
379
  self.assert201(response)
393
380
 
394
- response = self.get(url_for('api.user_contact_points', user=user))
381
+ response = self.get(url_for("api.user_contact_points", user=user))
395
382
  self.assert200(response)
396
383
 
397
- assert response.json['data'][0]['name'] == data['name']
398
- assert response.json['data'][0]['email'] == data['email']
384
+ assert response.json["data"][0]["name"] == data["name"]
385
+ assert response.json["data"][0]["email"] == data["email"]