udata 9.1.2.dev30355__py2.py3-none-any.whl → 9.1.2.dev30454__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 (413) 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 +111 -134
  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 +58 -55
  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/cors.py +99 -0
  199. udata/db/tasks.py +2 -1
  200. udata/entrypoints.py +35 -31
  201. udata/errors.py +2 -1
  202. udata/event/values.py +6 -6
  203. udata/factories.py +2 -2
  204. udata/features/identicon/api.py +5 -6
  205. udata/features/identicon/backends.py +48 -55
  206. udata/features/identicon/tests/test_backends.py +4 -5
  207. udata/features/notifications/__init__.py +0 -1
  208. udata/features/notifications/actions.py +9 -9
  209. udata/features/notifications/api.py +17 -13
  210. udata/features/territories/__init__.py +12 -10
  211. udata/features/territories/api.py +14 -15
  212. udata/features/territories/models.py +23 -28
  213. udata/features/transfer/actions.py +8 -11
  214. udata/features/transfer/api.py +84 -77
  215. udata/features/transfer/factories.py +2 -1
  216. udata/features/transfer/models.py +11 -12
  217. udata/features/transfer/notifications.py +19 -15
  218. udata/features/transfer/permissions.py +5 -5
  219. udata/forms/__init__.py +5 -2
  220. udata/forms/fields.py +164 -172
  221. udata/forms/validators.py +19 -22
  222. udata/forms/widgets.py +9 -13
  223. udata/frontend/__init__.py +31 -26
  224. udata/frontend/csv.py +68 -58
  225. udata/frontend/markdown.py +40 -44
  226. udata/harvest/actions.py +89 -77
  227. udata/harvest/api.py +294 -238
  228. udata/harvest/backends/__init__.py +4 -4
  229. udata/harvest/backends/base.py +128 -111
  230. udata/harvest/backends/dcat.py +80 -66
  231. udata/harvest/commands.py +56 -60
  232. udata/harvest/csv.py +8 -8
  233. udata/harvest/exceptions.py +6 -3
  234. udata/harvest/filters.py +24 -23
  235. udata/harvest/forms.py +27 -28
  236. udata/harvest/models.py +88 -80
  237. udata/harvest/notifications.py +15 -10
  238. udata/harvest/signals.py +13 -13
  239. udata/harvest/tasks.py +11 -10
  240. udata/harvest/tests/factories.py +23 -24
  241. udata/harvest/tests/test_actions.py +136 -166
  242. udata/harvest/tests/test_api.py +220 -214
  243. udata/harvest/tests/test_base_backend.py +117 -112
  244. udata/harvest/tests/test_dcat_backend.py +380 -308
  245. udata/harvest/tests/test_filters.py +33 -22
  246. udata/harvest/tests/test_models.py +11 -14
  247. udata/harvest/tests/test_notifications.py +6 -7
  248. udata/harvest/tests/test_tasks.py +7 -6
  249. udata/i18n.py +237 -78
  250. udata/linkchecker/backends.py +5 -11
  251. udata/linkchecker/checker.py +23 -22
  252. udata/linkchecker/commands.py +4 -6
  253. udata/linkchecker/models.py +6 -6
  254. udata/linkchecker/tasks.py +18 -20
  255. udata/mail.py +21 -21
  256. udata/migrations/2020-07-24-remove-s-from-scope-oauth.py +9 -8
  257. udata/migrations/2020-08-24-add-fs-filename.py +9 -8
  258. udata/migrations/2020-09-28-update-reuses-datasets-metrics.py +5 -4
  259. udata/migrations/2020-10-16-migrate-ods-resources.py +9 -10
  260. udata/migrations/2021-04-08-update-schema-with-new-structure.py +8 -7
  261. udata/migrations/2021-05-27-fix-default-schema-name.py +7 -6
  262. udata/migrations/2021-07-05-remove-unused-badges.py +17 -15
  263. udata/migrations/2021-07-07-update-schema-for-community-resources.py +7 -6
  264. udata/migrations/2021-08-17-follow-integrity.py +5 -4
  265. udata/migrations/2021-08-17-harvest-integrity.py +13 -12
  266. udata/migrations/2021-08-17-oauth2client-integrity.py +5 -4
  267. udata/migrations/2021-08-17-transfer-integrity.py +5 -4
  268. udata/migrations/2021-08-17-users-integrity.py +9 -8
  269. udata/migrations/2021-12-14-reuse-topics.py +7 -6
  270. udata/migrations/2022-04-21-improve-extension-detection.py +8 -7
  271. udata/migrations/2022-09-22-clean-inactive-harvest-datasets.py +16 -14
  272. udata/migrations/2022-10-10-add-fs_uniquifier-to-user-model.py +6 -6
  273. udata/migrations/2022-10-10-migrate-harvest-extras.py +36 -26
  274. udata/migrations/2023-02-08-rename-internal-dates.py +46 -28
  275. udata/migrations/2024-01-29-fix-reuse-and-dataset-with-private-None.py +10 -8
  276. udata/migrations/2024-03-22-migrate-activity-kwargs-to-extras.py +6 -4
  277. udata/migrations/2024-06-11-fix-reuse-datasets-references.py +7 -6
  278. udata/migrations/__init__.py +123 -105
  279. udata/models/__init__.py +4 -4
  280. udata/mongo/__init__.py +13 -11
  281. udata/mongo/badges_field.py +3 -2
  282. udata/mongo/datetime_fields.py +13 -12
  283. udata/mongo/document.py +17 -16
  284. udata/mongo/engine.py +15 -16
  285. udata/mongo/errors.py +2 -1
  286. udata/mongo/extras_fields.py +30 -20
  287. udata/mongo/queryset.py +12 -12
  288. udata/mongo/slug_fields.py +38 -28
  289. udata/mongo/taglist_field.py +1 -2
  290. udata/mongo/url_field.py +5 -5
  291. udata/mongo/uuid_fields.py +4 -3
  292. udata/notifications/__init__.py +1 -1
  293. udata/notifications/mattermost.py +10 -9
  294. udata/rdf.py +167 -188
  295. udata/routing.py +40 -45
  296. udata/search/__init__.py +18 -19
  297. udata/search/adapter.py +17 -16
  298. udata/search/commands.py +44 -51
  299. udata/search/fields.py +13 -20
  300. udata/search/query.py +23 -18
  301. udata/search/result.py +9 -10
  302. udata/sentry.py +21 -19
  303. udata/settings.py +262 -198
  304. udata/sitemap.py +8 -6
  305. udata/storage/s3.py +20 -13
  306. udata/tags.py +4 -5
  307. udata/tasks.py +43 -42
  308. udata/tests/__init__.py +9 -6
  309. udata/tests/api/__init__.py +8 -6
  310. udata/tests/api/test_auth_api.py +395 -321
  311. udata/tests/api/test_base_api.py +33 -35
  312. udata/tests/api/test_contact_points.py +7 -9
  313. udata/tests/api/test_dataservices_api.py +211 -158
  314. udata/tests/api/test_datasets_api.py +823 -812
  315. udata/tests/api/test_follow_api.py +13 -15
  316. udata/tests/api/test_me_api.py +95 -112
  317. udata/tests/api/test_organizations_api.py +301 -339
  318. udata/tests/api/test_reports_api.py +35 -25
  319. udata/tests/api/test_reuses_api.py +134 -139
  320. udata/tests/api/test_swagger.py +5 -5
  321. udata/tests/api/test_tags_api.py +18 -25
  322. udata/tests/api/test_topics_api.py +94 -94
  323. udata/tests/api/test_transfer_api.py +53 -48
  324. udata/tests/api/test_user_api.py +128 -141
  325. udata/tests/apiv2/test_datasets.py +290 -198
  326. udata/tests/apiv2/test_me_api.py +10 -11
  327. udata/tests/apiv2/test_organizations.py +56 -74
  328. udata/tests/apiv2/test_swagger.py +5 -5
  329. udata/tests/apiv2/test_topics.py +69 -87
  330. udata/tests/cli/test_cli_base.py +8 -8
  331. udata/tests/cli/test_db_cli.py +21 -19
  332. udata/tests/dataservice/test_dataservice_tasks.py +8 -12
  333. udata/tests/dataset/test_csv_adapter.py +44 -35
  334. udata/tests/dataset/test_dataset_actions.py +2 -3
  335. udata/tests/dataset/test_dataset_commands.py +7 -8
  336. udata/tests/dataset/test_dataset_events.py +36 -29
  337. udata/tests/dataset/test_dataset_model.py +224 -217
  338. udata/tests/dataset/test_dataset_rdf.py +142 -131
  339. udata/tests/dataset/test_dataset_tasks.py +15 -15
  340. udata/tests/dataset/test_resource_preview.py +10 -13
  341. udata/tests/features/territories/__init__.py +9 -13
  342. udata/tests/features/territories/test_territories_api.py +71 -91
  343. udata/tests/forms/test_basic_fields.py +7 -7
  344. udata/tests/forms/test_current_user_field.py +39 -66
  345. udata/tests/forms/test_daterange_field.py +31 -39
  346. udata/tests/forms/test_dict_field.py +28 -26
  347. udata/tests/forms/test_extras_fields.py +102 -76
  348. udata/tests/forms/test_form_field.py +8 -8
  349. udata/tests/forms/test_image_field.py +33 -26
  350. udata/tests/forms/test_model_field.py +134 -123
  351. udata/tests/forms/test_model_list_field.py +7 -7
  352. udata/tests/forms/test_nested_model_list_field.py +117 -79
  353. udata/tests/forms/test_publish_as_field.py +36 -65
  354. udata/tests/forms/test_reference_field.py +34 -53
  355. udata/tests/forms/test_user_forms.py +23 -21
  356. udata/tests/forms/test_uuid_field.py +6 -10
  357. udata/tests/frontend/__init__.py +9 -6
  358. udata/tests/frontend/test_auth.py +7 -6
  359. udata/tests/frontend/test_csv.py +81 -96
  360. udata/tests/frontend/test_hooks.py +43 -43
  361. udata/tests/frontend/test_markdown.py +211 -191
  362. udata/tests/helpers.py +32 -37
  363. udata/tests/models.py +2 -2
  364. udata/tests/organization/test_csv_adapter.py +21 -16
  365. udata/tests/organization/test_notifications.py +11 -18
  366. udata/tests/organization/test_organization_model.py +13 -13
  367. udata/tests/organization/test_organization_rdf.py +29 -22
  368. udata/tests/organization/test_organization_tasks.py +16 -17
  369. udata/tests/plugin.py +79 -73
  370. udata/tests/reuse/test_reuse_model.py +21 -21
  371. udata/tests/reuse/test_reuse_task.py +11 -13
  372. udata/tests/search/__init__.py +11 -12
  373. udata/tests/search/test_adapter.py +60 -70
  374. udata/tests/search/test_query.py +16 -16
  375. udata/tests/search/test_results.py +10 -7
  376. udata/tests/site/test_site_api.py +11 -16
  377. udata/tests/site/test_site_metrics.py +20 -30
  378. udata/tests/site/test_site_model.py +4 -5
  379. udata/tests/site/test_site_rdf.py +94 -78
  380. udata/tests/test_activity.py +17 -17
  381. udata/tests/test_cors.py +62 -0
  382. udata/tests/test_discussions.py +292 -299
  383. udata/tests/test_i18n.py +37 -40
  384. udata/tests/test_linkchecker.py +91 -85
  385. udata/tests/test_mail.py +13 -17
  386. udata/tests/test_migrations.py +219 -180
  387. udata/tests/test_model.py +164 -157
  388. udata/tests/test_notifications.py +17 -17
  389. udata/tests/test_owned.py +14 -14
  390. udata/tests/test_rdf.py +25 -23
  391. udata/tests/test_routing.py +89 -93
  392. udata/tests/test_storages.py +137 -128
  393. udata/tests/test_tags.py +44 -46
  394. udata/tests/test_topics.py +7 -7
  395. udata/tests/test_transfer.py +42 -49
  396. udata/tests/test_uris.py +160 -161
  397. udata/tests/test_utils.py +79 -71
  398. udata/tests/user/test_user_rdf.py +5 -9
  399. udata/tests/workers/test_jobs_commands.py +57 -58
  400. udata/tests/workers/test_tasks_routing.py +23 -29
  401. udata/tests/workers/test_workers_api.py +125 -131
  402. udata/tests/workers/test_workers_helpers.py +6 -6
  403. udata/tracking.py +4 -6
  404. udata/uris.py +45 -46
  405. udata/utils.py +68 -66
  406. udata/wsgi.py +1 -1
  407. {udata-9.1.2.dev30355.dist-info → udata-9.1.2.dev30454.dist-info}/METADATA +7 -3
  408. udata-9.1.2.dev30454.dist-info/RECORD +706 -0
  409. udata-9.1.2.dev30355.dist-info/RECORD +0 -704
  410. {udata-9.1.2.dev30355.dist-info → udata-9.1.2.dev30454.dist-info}/LICENSE +0 -0
  411. {udata-9.1.2.dev30355.dist-info → udata-9.1.2.dev30454.dist-info}/WHEEL +0 -0
  412. {udata-9.1.2.dev30355.dist-info → udata-9.1.2.dev30454.dist-info}/entry_points.txt +0 -0
  413. {udata-9.1.2.dev30355.dist-info → udata-9.1.2.dev30454.dist-info}/top_level.txt +0 -0
udata/tests/helpers.py CHANGED
@@ -1,37 +1,32 @@
1
- import mock
2
1
  import os
3
-
2
+ from contextlib import contextmanager
3
+ from datetime import timedelta
4
4
  from io import BytesIO
5
+ from urllib.parse import parse_qs, urljoin, urlparse
5
6
 
7
+ import mock
8
+ from flask import current_app, json, request, url_for
9
+ from flask_security.babel import FsDomain
6
10
  from PIL import Image
7
11
 
8
12
  from udata.mail import mail_sent
9
13
 
10
- from contextlib import contextmanager
11
- from datetime import timedelta
12
- from urllib.parse import urljoin, urlparse, parse_qs
13
-
14
- from flask import request, url_for, json, current_app
15
- from flask_security.babel import FsDomain
16
-
17
14
 
18
15
  def assert_equal_dates(datetime1, datetime2, limit=1): # Seconds.
19
16
  """Lax date comparison, avoid comparing milliseconds and seconds."""
20
17
  __tracebackhide__ = True
21
- delta = (datetime1 - datetime2)
18
+ delta = datetime1 - datetime2
22
19
  assert timedelta(seconds=-limit) <= delta <= timedelta(seconds=limit)
23
20
 
24
21
 
25
22
  def assert_starts_with(haystack, needle):
26
23
  __tracebackhide__ = True
27
- msg = '{haystack} does not start with {needle}'.format(
28
- haystack=haystack, needle=needle
29
- )
24
+ msg = "{haystack} does not start with {needle}".format(haystack=haystack, needle=needle)
30
25
  assert haystack.startswith(needle), msg
31
26
 
32
27
 
33
28
  def assert_json_equal(first, second):
34
- '''Ensure two dict produce the same JSON'''
29
+ """Ensure two dict produce the same JSON"""
35
30
  __tracebackhide__ = True
36
31
  json1 = json.loads(json.dumps(first))
37
32
  json2 = json.loads(json.dumps(second))
@@ -55,12 +50,12 @@ def mock_signals(callback, *signals):
55
50
 
56
51
  for signal, mock_handler in specs:
57
52
  signal.disconnect(mock_handler)
58
- signal_name = getattr(signal, 'name', str(signal))
53
+ signal_name = getattr(signal, "name", str(signal))
59
54
  callback(signal_name, mock_handler)
60
55
 
61
56
 
62
57
  @contextmanager
63
- def assert_emit(*signals, assertions_callback = None):
58
+ def assert_emit(*signals, assertions_callback=None):
64
59
  __tracebackhide__ = True
65
60
  msg = 'Signal "{0}" should have been emitted'
66
61
 
@@ -100,8 +95,8 @@ def capture_mails():
100
95
 
101
96
 
102
97
  REDIRECT_CODES = (301, 302, 303, 305, 307, 308)
103
- REDIRECT_MSG = 'HTTP Status {} expected but got {{}}'.format(
104
- ', '.join(str(code) for code in REDIRECT_CODES)
98
+ REDIRECT_MSG = "HTTP Status {} expected but got {{}}".format(
99
+ ", ".join(str(code) for code in REDIRECT_CODES)
105
100
  )
106
101
 
107
102
 
@@ -132,12 +127,11 @@ def assert_status(response, status_code, message=None):
132
127
  """
133
128
  __tracebackhide__ = True
134
129
 
135
- message = message or 'HTTP Status %s expected but got %s' \
136
- % (status_code, response.status_code)
137
- if response.mimetype == 'application/json':
130
+ message = message or "HTTP Status %s expected but got %s" % (status_code, response.status_code)
131
+ if response.mimetype == "application/json":
138
132
  try:
139
- second_line = 'Response content is {0}'.format(response.json)
140
- message = '\n'.join((message, second_line))
133
+ second_line = "Response content is {0}".format(response.json)
134
+ message = "\n".join((message, second_line))
141
135
  except Exception:
142
136
  pass
143
137
  assert response.status_code == status_code, message
@@ -189,18 +183,18 @@ def assert500(response):
189
183
 
190
184
 
191
185
  def full_url(*args, **kwargs):
192
- '''Build a full URL'''
186
+ """Build a full URL"""
193
187
  return urljoin(request.url_root, url_for(*args, **kwargs))
194
188
 
195
189
 
196
190
  def data_path(filename):
197
- '''Get a test data path'''
198
- return os.path.join(os.path.dirname(__file__), 'data', filename)
191
+ """Get a test data path"""
192
+ return os.path.join(os.path.dirname(__file__), "data", filename)
199
193
 
200
194
 
201
195
  def assert_command_ok(result):
202
196
  __tracebackhide__ = True
203
- msg = 'Command failed with exit code {0.exit_code} and output:\n{0.output}'
197
+ msg = "Command failed with exit code {0.exit_code} and output:\n{0.output}"
204
198
  assert result.exit_code == 0, msg.format(result)
205
199
 
206
200
 
@@ -208,28 +202,29 @@ def assert_urls_equal(url1, url2):
208
202
  __tracebackhide__ = True
209
203
  p1 = urlparse(url1)
210
204
  p2 = urlparse(url2)
211
- assert p1.scheme == p2.scheme, 'Scheme does not match'
212
- assert p1.netloc == p2.netloc, 'Network location does not match'
213
- assert p1.path == p2.path, 'Path does not match'
205
+ assert p1.scheme == p2.scheme, "Scheme does not match"
206
+ assert p1.netloc == p2.netloc, "Network location does not match"
207
+ assert p1.path == p2.path, "Path does not match"
214
208
  q1 = parse_qs(p1.query)
215
209
  q2 = parse_qs(p2.query)
216
- assert q1 == q2, 'Query does not match'
217
- assert p1.fragment == p2.fragment, 'Fragment does not match'
210
+ assert q1 == q2, "Query does not match"
211
+ assert p1.fragment == p2.fragment, "Fragment does not match"
218
212
 
219
213
 
220
214
  def assert_cors(response):
221
- '''CORS headers presence assertion'''
215
+ """CORS headers presence assertion"""
222
216
  __tracebackhide__ = True
223
- assert 'Access-Control-Allow-Origin' in response.headers
217
+ assert "Access-Control-Allow-Origin" in response.headers
224
218
 
225
219
 
226
220
  def create_test_image():
227
221
  file = BytesIO()
228
- image = Image.new('RGBA', size=(50, 50), color=(155, 0, 0))
229
- image.save(file, 'png')
230
- file.name = 'test.png'
222
+ image = Image.new("RGBA", size=(50, 50), color=(155, 0, 0))
223
+ image.save(file, "png")
224
+ file.name = "test.png"
231
225
  file.seek(0)
232
226
  return file
233
227
 
228
+
234
229
  def security_gettext(string):
235
230
  return FsDomain(current_app).gettext(string)
udata/tests/models.py CHANGED
@@ -1,11 +1,11 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  from __future__ import unicode_literals
3
3
 
4
- from udata.models import db, WithMetrics
4
+ from udata.models import WithMetrics, db
5
5
 
6
6
 
7
7
  class FakeModel(WithMetrics, db.Document):
8
8
  name = db.StringField()
9
9
 
10
10
  def __unicode__(self):
11
- return self.name or ''
11
+ return self.name or ""
@@ -1,7 +1,6 @@
1
-
2
1
  import pytest
3
2
 
4
- from udata.core.dataset.csv import ResourcesCsvAdapter, DatasetCsvAdapter
3
+ from udata.core.dataset.csv import DatasetCsvAdapter, ResourcesCsvAdapter
5
4
  from udata.core.dataset.factories import DatasetFactory, ResourceFactory
6
5
  from udata.core.dataset.models import Dataset
7
6
  from udata.core.organization.csv import OrganizationCsvAdapter
@@ -10,22 +9,28 @@ from udata.core.organization.models import Organization
10
9
 
11
10
 
12
11
  @pytest.mark.frontend
13
- @pytest.mark.usefixtures('clean_db')
12
+ @pytest.mark.usefixtures("clean_db")
14
13
  class OrganizationCSVAdapterTest:
15
-
16
14
  def test_organization_downloads_counts(self):
17
15
  org_with_dataset = OrganizationFactory()
18
16
  org_without_dataset = OrganizationFactory()
19
17
 
20
- DatasetFactory(organization=org_with_dataset, resources=[
21
- ResourceFactory(metrics={
22
- 'views': 42,
23
- }),
24
- ResourceFactory(metrics={
25
- 'views': 1337,
26
- }),
27
- ResourceFactory(),
28
- ])
18
+ DatasetFactory(
19
+ organization=org_with_dataset,
20
+ resources=[
21
+ ResourceFactory(
22
+ metrics={
23
+ "views": 42,
24
+ }
25
+ ),
26
+ ResourceFactory(
27
+ metrics={
28
+ "views": 1337,
29
+ }
30
+ ),
31
+ ResourceFactory(),
32
+ ],
33
+ )
29
34
  DatasetFactory(organization=org_with_dataset, resources=[])
30
35
  adapter = OrganizationCsvAdapter(Organization.objects.all())
31
36
 
@@ -33,10 +38,10 @@ class OrganizationCSVAdapterTest:
33
38
  csv = {}
34
39
  for row in adapter.rows():
35
40
  values = dict(zip(adapter.header(), row))
36
- csv[values['id']] = values
41
+ csv[values["id"]] = values
37
42
 
38
43
  org_values = csv[str(org_with_dataset.id)]
39
- assert org_values['downloads'] == 1337 + 42
44
+ assert org_values["downloads"] == 1337 + 42
40
45
 
41
46
  org_values = csv[str(org_without_dataset.id)]
42
- assert org_values['downloads'] == 0
47
+ assert org_values["downloads"] == 0
@@ -1,27 +1,20 @@
1
1
  import pytest
2
2
 
3
- from udata.models import MembershipRequest, Member
4
-
5
- from udata.core.user.factories import UserFactory
6
3
  from udata.core.organization.factories import OrganizationFactory
7
- from udata.core.organization.notifications import (
8
- membership_request_notifications
9
- )
10
-
4
+ from udata.core.organization.notifications import membership_request_notifications
5
+ from udata.core.user.factories import UserFactory
6
+ from udata.models import Member, MembershipRequest
11
7
  from udata.tests.helpers import assert_equal_dates
12
8
 
13
9
 
14
- @pytest.mark.usefixtures('clean_db')
10
+ @pytest.mark.usefixtures("clean_db")
15
11
  class OrganizationNotificationsTest:
16
12
  def test_pending_membership_requests(self):
17
13
  admin = UserFactory()
18
14
  editor = UserFactory()
19
15
  applicant = UserFactory()
20
- request = MembershipRequest(user=applicant, comment='test')
21
- members = [
22
- Member(user=editor, role='editor'),
23
- Member(user=admin, role='admin')
24
- ]
16
+ request = MembershipRequest(user=applicant, comment="test")
17
+ members = [Member(user=editor, role="editor"), Member(user=admin, role="admin")]
25
18
  org = OrganizationFactory(members=members, requests=[request])
26
19
 
27
20
  assert len(membership_request_notifications(applicant)) is 0
@@ -31,8 +24,8 @@ class OrganizationNotificationsTest:
31
24
  assert len(notifications) is 1
32
25
  dt, details = notifications[0]
33
26
  assert_equal_dates(dt, request.created)
34
- assert details['id'] == request.id
35
- assert details['organization'] == org.id
36
- assert details['user']['id'] == applicant.id
37
- assert details['user']['fullname'] == applicant.fullname
38
- assert details['user']['avatar'] == str(applicant.avatar)
27
+ assert details["id"] == request.id
28
+ assert details["organization"] == org.id
29
+ assert details["user"]["id"] == applicant.id
30
+ assert details["user"]["fullname"] == applicant.fullname
31
+ assert details["user"]["avatar"] == str(applicant.avatar)
@@ -1,18 +1,17 @@
1
1
  from datetime import datetime
2
2
 
3
3
  from udata.core.dataset.factories import DatasetFactory, HiddenDatasetFactory
4
- from udata.core.organization.factories import OrganizationFactory
5
4
  from udata.core.followers.signals import on_follow, on_unfollow
5
+ from udata.core.organization.factories import OrganizationFactory
6
6
  from udata.core.reuse.factories import ReuseFactory, VisibleReuseFactory
7
7
  from udata.core.user.factories import UserFactory
8
- from udata.models import Dataset, Reuse, Follow, Member
8
+ from udata.models import Dataset, Follow, Member, Reuse
9
9
  from udata.tests.helpers import assert_emit
10
10
 
11
- from .. import TestCase, DBTestMixin
11
+ from .. import DBTestMixin, TestCase
12
12
 
13
13
 
14
14
  class OrganizationModelTest(TestCase, DBTestMixin):
15
-
16
15
  # Load metrics
17
16
  import udata.core.organization.metrics # noqa
18
17
  import udata.core.followers.metrics # noqa
@@ -20,7 +19,7 @@ class OrganizationModelTest(TestCase, DBTestMixin):
20
19
  def test_organization_metrics(self):
21
20
  # Members count update are in API calls, thus being tested in API dedicated tests
22
21
 
23
- member = Member(user=UserFactory(), role='admin')
22
+ member = Member(user=UserFactory(), role="admin")
24
23
  org = OrganizationFactory(members=[member])
25
24
 
26
25
  with assert_emit(Reuse.on_create):
@@ -30,12 +29,13 @@ class OrganizationModelTest(TestCase, DBTestMixin):
30
29
  dataset = DatasetFactory(organization=org)
31
30
  HiddenDatasetFactory(organization=org)
32
31
  with assert_emit(on_follow):
33
- follow = Follow.objects.create(following=org, follower=UserFactory(),
34
- since=datetime.utcnow())
32
+ follow = Follow.objects.create(
33
+ following=org, follower=UserFactory(), since=datetime.utcnow()
34
+ )
35
35
 
36
- assert org.get_metrics()['datasets'] == 1
37
- assert org.get_metrics()['reuses'] == 1
38
- assert org.get_metrics()['followers'] == 1
36
+ assert org.get_metrics()["datasets"] == 1
37
+ assert org.get_metrics()["reuses"] == 1
38
+ assert org.get_metrics()["followers"] == 1
39
39
 
40
40
  with assert_emit(Reuse.on_delete):
41
41
  reuse.deleted = datetime.utcnow()
@@ -47,6 +47,6 @@ class OrganizationModelTest(TestCase, DBTestMixin):
47
47
  follow.until = datetime.utcnow()
48
48
  follow.save()
49
49
 
50
- assert org.get_metrics()['datasets'] == 0
51
- assert org.get_metrics()['reuses'] == 0
52
- assert org.get_metrics()['followers'] == 0
50
+ assert org.get_metrics()["datasets"] == 0
51
+ assert org.get_metrics()["reuses"] == 0
52
+ assert org.get_metrics()["followers"] == 0
@@ -1,16 +1,15 @@
1
1
  from flask import url_for
2
-
3
- from rdflib import URIRef, Literal, BNode
4
- from rdflib.namespace import RDF, FOAF, RDFS
2
+ from rdflib import BNode, Literal, URIRef
3
+ from rdflib.namespace import FOAF, RDF, RDFS
5
4
  from rdflib.resource import Resource as RdfResource
6
5
 
7
6
  from udata import api
8
- from udata.rdf import DCAT, DCT, HYDRA
9
- from udata.tests import TestCase, DBTestMixin
10
- from udata.core.organization.factories import OrganizationFactory
11
- from udata.core.organization.rdf import organization_to_rdf, build_org_catalog
12
7
  from udata.core.dataset.factories import DatasetFactory
13
8
  from udata.core.dataset.models import Dataset
9
+ from udata.core.organization.factories import OrganizationFactory
10
+ from udata.core.organization.rdf import build_org_catalog, organization_to_rdf
11
+ from udata.rdf import DCAT, DCT, HYDRA
12
+ from udata.tests import DBTestMixin, TestCase
14
13
  from udata.utils import faker
15
14
 
16
15
 
@@ -36,9 +35,7 @@ class OrganizationToRdfTest(DBTestMixin, TestCase):
36
35
 
37
36
  def test_all_fields(self):
38
37
  org = OrganizationFactory(url=faker.uri())
39
- org_url = url_for('api.organization',
40
- org=org.id,
41
- _external=True)
38
+ org_url = url_for("api.organization", org=org.id, _external=True)
42
39
  o = organization_to_rdf(org)
43
40
  g = o.graph
44
41
 
@@ -55,7 +52,7 @@ class OrganizationToRdfTest(DBTestMixin, TestCase):
55
52
 
56
53
  def test_catalog(self):
57
54
  origin_org = OrganizationFactory()
58
- uri = url_for('api.organization_rdf', org=origin_org.id, _external=True)
55
+ uri = url_for("api.organization_rdf", org=origin_org.id, _external=True)
59
56
 
60
57
  datasets = DatasetFactory.create_batch(3, organization=origin_org)
61
58
  catalog = build_org_catalog(origin_org, datasets)
@@ -88,16 +85,28 @@ class OrganizationToRdfTest(DBTestMixin, TestCase):
88
85
  origin_org = OrganizationFactory()
89
86
  page_size = 3
90
87
  total = 4
91
- uri = url_for('api.organization_rdf', org=origin_org.id, _external=True)
92
- uri_first = url_for('api.organization_rdf_format', org=origin_org.id, format='json',
93
- page=1, page_size=page_size, _external=True)
94
- uri_last = url_for('api.organization_rdf_format', org=origin_org.id, format='json',
95
- page=2, page_size=page_size, _external=True)
88
+ uri = url_for("api.organization_rdf", org=origin_org.id, _external=True)
89
+ uri_first = url_for(
90
+ "api.organization_rdf_format",
91
+ org=origin_org.id,
92
+ format="json",
93
+ page=1,
94
+ page_size=page_size,
95
+ _external=True,
96
+ )
97
+ uri_last = url_for(
98
+ "api.organization_rdf_format",
99
+ org=origin_org.id,
100
+ format="json",
101
+ page=2,
102
+ page_size=page_size,
103
+ _external=True,
104
+ )
96
105
  DatasetFactory.create_batch(total, organization=origin_org)
97
106
 
98
107
  # First page
99
108
  datasets = Dataset.objects.paginate(1, page_size)
100
- catalog = build_org_catalog(origin_org, datasets, format='json')
109
+ catalog = build_org_catalog(origin_org, datasets, format="json")
101
110
  graph = catalog.graph
102
111
 
103
112
  self.assertIsInstance(catalog, RdfResource)
@@ -110,8 +119,7 @@ class OrganizationToRdfTest(DBTestMixin, TestCase):
110
119
 
111
120
  self.assertEqual(len(list(catalog.objects(DCAT.dataset))), page_size)
112
121
 
113
- paginations = list(graph.subjects(RDF.type,
114
- HYDRA.PartialCollectionView))
122
+ paginations = list(graph.subjects(RDF.type, HYDRA.PartialCollectionView))
115
123
  self.assertEqual(len(paginations), 1)
116
124
  pagination = graph.resource(paginations[0])
117
125
  self.assertEqual(pagination.identifier, URIRef(uri_first))
@@ -122,7 +130,7 @@ class OrganizationToRdfTest(DBTestMixin, TestCase):
122
130
 
123
131
  # Second page
124
132
  datasets = Dataset.objects.paginate(2, page_size)
125
- catalog = build_org_catalog(origin_org, datasets, format='json')
133
+ catalog = build_org_catalog(origin_org, datasets, format="json")
126
134
  graph = catalog.graph
127
135
 
128
136
  self.assertIsInstance(catalog, RdfResource)
@@ -135,8 +143,7 @@ class OrganizationToRdfTest(DBTestMixin, TestCase):
135
143
 
136
144
  self.assertEqual(len(list(catalog.objects(DCAT.dataset))), 1)
137
145
 
138
- paginations = list(graph.subjects(RDF.type,
139
- HYDRA.PartialCollectionView))
146
+ paginations = list(graph.subjects(RDF.type, HYDRA.PartialCollectionView))
140
147
  self.assertEqual(len(paginations), 1)
141
148
  pagination = graph.resource(paginations[0])
142
149
  self.assertEqual(pagination.identifier, URIRef(uri_last))
@@ -3,9 +3,9 @@ from flask import url_for
3
3
  from udata.api.oauth2 import OAuth2Client
4
4
  from udata.core import storages
5
5
  from udata.core.dataset.factories import DatasetFactory, ResourceFactory
6
- from udata.core.user.factories import AdminFactory
7
6
  from udata.core.organization import tasks
8
- from udata.models import Dataset, Organization, Transfer, Member, ContactPoint
7
+ from udata.core.user.factories import AdminFactory
8
+ from udata.models import ContactPoint, Dataset, Member, Organization, Transfer
9
9
  from udata.tests.api import APITestCase
10
10
  from udata.tests.helpers import create_test_image
11
11
 
@@ -13,14 +13,14 @@ from udata.tests.helpers import create_test_image
13
13
  class OrganizationTasksTest(APITestCase):
14
14
  def test_purge_organizations(self):
15
15
  self.login()
16
- member = Member(user=self.user, role='admin')
17
- org = Organization.objects.create(name='delete me', description='XXX', members=[member])
16
+ member = Member(user=self.user, role="admin")
17
+ org = Organization.objects.create(name="delete me", description="XXX", members=[member])
18
18
  data = {
19
- 'email': 'mooneywayne@cobb-cochran.com',
20
- 'name': 'Martin Schultz',
21
- 'organization': str(org.id)
19
+ "email": "mooneywayne@cobb-cochran.com",
20
+ "name": "Martin Schultz",
21
+ "organization": str(org.id),
22
22
  }
23
- response = self.post(url_for('api.contact_points'), data)
23
+ response = self.post(url_for("api.contact_points"), data)
24
24
  self.assert201(response)
25
25
 
26
26
  self.assertEqual(ContactPoint.objects().count(), 1)
@@ -33,33 +33,32 @@ class OrganizationTasksTest(APITestCase):
33
33
  user = AdminFactory()
34
34
  self.login(user)
35
35
  response = self.post(
36
- url_for('api.organization_logo', org=org),
37
- {'file': (file, 'test.png')},
38
- json=False)
36
+ url_for("api.organization_logo", org=org), {"file": (file, "test.png")}, json=False
37
+ )
39
38
  self.assert200(response)
40
39
 
41
40
  transfer_to_org = Transfer.objects.create(
42
41
  owner=user,
43
42
  recipient=org,
44
43
  subject=dataset,
45
- comment='comment',
44
+ comment="comment",
46
45
  )
47
46
  transfer_from_org = Transfer.objects.create(
48
47
  owner=org,
49
48
  recipient=user,
50
49
  subject=dataset,
51
- comment='comment',
50
+ comment="comment",
52
51
  )
53
52
 
54
53
  oauth_client = OAuth2Client.objects.create(
55
- name='test-client',
54
+ name="test-client",
56
55
  owner=user,
57
56
  organization=org,
58
- redirect_uris=['https://test.org/callback'],
57
+ redirect_uris=["https://test.org/callback"],
59
58
  )
60
59
 
61
60
  # Delete organization
62
- response = self.delete(url_for('api.organization', org=org))
61
+ response = self.delete(url_for("api.organization", org=org))
63
62
  self.assert204(response)
64
63
 
65
64
  tasks.purge_organizations()
@@ -79,5 +78,5 @@ class OrganizationTasksTest(APITestCase):
79
78
  dataset = Dataset.objects(id=dataset.id).first()
80
79
  self.assertIsNone(dataset.organization)
81
80
 
82
- organization = Organization.objects(name='delete me').first()
81
+ organization = Organization.objects(name="delete me").first()
83
82
  self.assertIsNone(organization)