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/test_i18n.py CHANGED
@@ -1,32 +1,31 @@
1
- from flask import g, url_for, render_template_string
1
+ from flask import g, render_template_string, url_for
2
2
  from werkzeug.routing import BuildError
3
3
 
4
- from udata.i18n import I18nBlueprint, language
5
-
6
- from . import DBTestMixin, WebTestMixin, TestCase
7
4
  from udata.core.user.factories import UserFactory
5
+ from udata.i18n import I18nBlueprint, language
8
6
 
7
+ from . import DBTestMixin, TestCase, WebTestMixin
9
8
 
10
- bp = I18nBlueprint('i18nbp', __name__, static_folder='static')
9
+ bp = I18nBlueprint("i18nbp", __name__, static_folder="static")
11
10
 
12
11
 
13
- @bp.route('/lang/<msg>/')
12
+ @bp.route("/lang/<msg>/")
14
13
  def lang(msg):
15
14
  return g.lang_code
16
15
 
17
16
 
18
- @bp.route('/hardcoded/')
17
+ @bp.route("/hardcoded/")
19
18
  def hardcoded():
20
- out = g.lang_code + '-'
21
- with language('fr'):
19
+ out = g.lang_code + "-"
20
+ with language("fr"):
22
21
  out += g.lang_code
23
22
  return out
24
23
 
25
24
 
26
- @bp.route('/not-localized/', localize=False)
25
+ @bp.route("/not-localized/", localize=False)
27
26
  def not_localized():
28
- out = g.lang_code + '-'
29
- with language('fr'):
27
+ out = g.lang_code + "-"
28
+ with language("fr"):
30
29
  out += g.lang_code
31
30
  return out
32
31
 
@@ -34,63 +33,61 @@ def not_localized():
34
33
  class I18nBlueprintTest(WebTestMixin, DBTestMixin, TestCase):
35
34
  def create_app(self):
36
35
  app = super(I18nBlueprintTest, self).create_app()
37
- app.config['DEFAULT_LANGUAGE'] = 'en'
38
- app.config['LANGUAGES'] = {
39
- 'en': 'English',
40
- 'fr': 'Français',
36
+ app.config["DEFAULT_LANGUAGE"] = "en"
37
+ app.config["LANGUAGES"] = {
38
+ "en": "English",
39
+ "fr": "Français",
41
40
  }
42
41
  app.register_blueprint(bp)
43
42
  return app
44
43
 
45
44
  def test_lang_inserted_url_for(self):
46
- self.assertEqual(url_for('i18nbp.lang', msg='test'), '/en/lang/test/')
45
+ self.assertEqual(url_for("i18nbp.lang", msg="test"), "/en/lang/test/")
47
46
 
48
47
  def test_redirect_url_for(self):
49
- self.assertEqual(
50
- url_for('i18nbp.lang_redirect', msg='test'), '/lang/test/')
48
+ self.assertEqual(url_for("i18nbp.lang_redirect", msg="test"), "/lang/test/")
51
49
 
52
50
  def test_lang_ignored_for_static(self):
53
- self.assertEqual(url_for('i18nbp.static', filename='test.jpg'),
54
- '/static/test.jpg')
51
+ self.assertEqual(url_for("i18nbp.static", filename="test.jpg"), "/static/test.jpg")
55
52
  with self.assertRaises(BuildError):
56
- url_for('i18nbp.static_redirect', filename='test.jpg')
53
+ url_for("i18nbp.static_redirect", filename="test.jpg")
57
54
 
58
55
  def test_redirect_on_missing_lang(self):
59
- response = self.get('/lang/test/?q=test')
60
- self.assertRedirects(response, '/en/lang/test/?q=test')
56
+ response = self.get("/lang/test/?q=test")
57
+ self.assertRedirects(response, "/en/lang/test/?q=test")
61
58
 
62
59
  def test_do_not_redirect_and_set_lang(self):
63
- self.assertEqual(self.get('/fr/lang/test/').data, b'fr')
64
- self.assertEqual(self.get('/en/lang/test/').data, b'en')
60
+ self.assertEqual(self.get("/fr/lang/test/").data, b"fr")
61
+ self.assertEqual(self.get("/en/lang/test/").data, b"en")
65
62
 
66
63
  def test_redirect_on_default_lang_for_unknown_lang(self):
67
- self.assertRedirects(self.get('/sk/lang/test/'), '/en/lang/test/')
64
+ self.assertRedirects(self.get("/sk/lang/test/"), "/en/lang/test/")
68
65
 
69
66
  def test_404_on_default_lang_for_unknown_lang(self):
70
- self.assert404(self.get('/sk/not-found/'))
67
+ self.assert404(self.get("/sk/not-found/"))
71
68
 
72
69
  def test_language_contact_manager(self):
73
- self.assertEqual(self.get('/fr/hardcoded/').data, b'fr-fr')
74
- self.assertEqual(self.get('/en/hardcoded/').data, b'en-fr')
70
+ self.assertEqual(self.get("/fr/hardcoded/").data, b"fr-fr")
71
+ self.assertEqual(self.get("/en/hardcoded/").data, b"en-fr")
75
72
 
76
73
  def test_redirect_user_prefered_lang(self):
77
- self.login(UserFactory(prefered_language='fr'))
74
+ self.login(UserFactory(prefered_language="fr"))
78
75
 
79
- response = self.get('/lang/test/?q=test')
80
- self.assertRedirects(response, '/fr/lang/test/?q=test')
76
+ response = self.get("/lang/test/?q=test")
77
+ self.assertRedirects(response, "/fr/lang/test/?q=test")
81
78
 
82
79
  def test_lang_ignored_for_localize_false(self):
83
- url = url_for('i18nbp.not_localized')
84
- self.assertEqual(url, '/not-localized/')
80
+ url = url_for("i18nbp.not_localized")
81
+ self.assertEqual(url, "/not-localized/")
85
82
 
86
83
  def test_localized_url_redirect_for_localize_false(self):
87
- url = url_for('i18nbp.not_localized_redirect')
88
- self.assertEqual(url, '/en/not-localized/')
84
+ url = url_for("i18nbp.not_localized_redirect")
85
+ self.assertEqual(url, "/en/not-localized/")
89
86
 
90
87
  response = self.get(url)
91
- self.assertRedirects(response, '/not-localized/')
88
+ self.assertRedirects(response, "/not-localized/")
92
89
 
93
90
  def test_render_template_translation(self):
94
- '''It should render the dataset page'''
95
- self.app.config['DEFAULT_LANGUAGE'] = 'fr'
91
+ """It should render the dataset page"""
92
+ self.app.config["DEFAULT_LANGUAGE"] = "fr"
96
93
  self.assertEqual("Bienvenue", render_template_string('{{ _("Welcome") }}'))
@@ -1,21 +1,22 @@
1
+ from datetime import datetime, timedelta
2
+
1
3
  import mock
2
4
  import pytest
3
- from datetime import datetime, timedelta
4
5
 
5
6
  from udata.auth import login_user
6
- from udata.tests import TestCase
7
7
  from udata.core.activity import init_app as init_activity
8
8
  from udata.core.activity.models import Activity
9
9
  from udata.core.dataset.factories import DatasetFactory, ResourceFactory
10
10
  from udata.core.user.factories import UserFactory
11
11
  from udata.linkchecker.checker import check_resource
12
12
  from udata.settings import Testing
13
+ from udata.tests import TestCase
13
14
 
14
15
 
15
16
  class LinkcheckerTestSettings(Testing):
16
17
  LINKCHECKING_ENABLED = True
17
- LINKCHECKING_IGNORE_DOMAINS = ['example-ignore.com']
18
- LINKCHECKING_IGNORE_PATTERNS = ['format=shp']
18
+ LINKCHECKING_IGNORE_DOMAINS = ["example-ignore.com"]
19
+ LINKCHECKING_IGNORE_PATTERNS = ["format=shp"]
19
20
  LINKCHECKING_MIN_CACHE_DURATION = 0.5
20
21
  LINKCHECKING_UNAVAILABLE_THRESHOLD = 100
21
22
  LINKCHECKING_MAX_CACHE_DURATION = 100
@@ -32,14 +33,13 @@ def test_check_resource_creates_no_activity(activity_app, mocker):
32
33
  dataset = DatasetFactory(resources=[resource])
33
34
  user = UserFactory()
34
35
  login_user(user)
35
- check_res = {'check:status': 200, 'check:available': True,
36
- 'check:date': datetime.utcnow()}
36
+ check_res = {"check:status": 200, "check:available": True, "check:date": datetime.utcnow()}
37
37
 
38
38
  class DummyLinkchecker:
39
39
  def check(self, _):
40
40
  return check_res
41
- mocker.patch('udata.linkchecker.checker.get_linkchecker',
42
- return_value=DummyLinkchecker)
41
+
42
+ mocker.patch("udata.linkchecker.checker.get_linkchecker", return_value=DummyLinkchecker)
43
43
 
44
44
  check_resource(resource)
45
45
 
@@ -54,95 +54,98 @@ class LinkcheckerTest(TestCase):
54
54
  self.resource = ResourceFactory()
55
55
  self.dataset = DatasetFactory(resources=[self.resource])
56
56
 
57
- @mock.patch('udata.linkchecker.checker.get_linkchecker')
57
+ @mock.patch("udata.linkchecker.checker.get_linkchecker")
58
58
  def test_check_resource_no_linkchecker(self, mock_fn):
59
59
  mock_fn.return_value = None
60
60
  res = check_resource(self.resource)
61
- self.assertEqual(res, ({'error': 'No linkchecker configured.'}, 503))
61
+ self.assertEqual(res, ({"error": "No linkchecker configured."}, 503))
62
62
 
63
- @mock.patch('udata.linkchecker.checker.get_linkchecker')
63
+ @mock.patch("udata.linkchecker.checker.get_linkchecker")
64
64
  def test_check_resource_linkchecker_ok(self, mock_fn):
65
- check_res = {'check:status': 200, 'check:available': True,
66
- 'check:date': datetime.utcnow()}
65
+ check_res = {"check:status": 200, "check:available": True, "check:date": datetime.utcnow()}
67
66
 
68
67
  class DummyLinkchecker:
69
68
  def check(self, _):
70
69
  return check_res
70
+
71
71
  mock_fn.return_value = DummyLinkchecker
72
72
 
73
73
  res = check_resource(self.resource)
74
74
  self.assertEqual(res, check_res)
75
- check_res.update({'check:count-availability': 1})
75
+ check_res.update({"check:count-availability": 1})
76
76
  self.assertEqual(self.resource.extras, check_res)
77
77
 
78
- @mock.patch('udata.linkchecker.checker.get_linkchecker')
78
+ @mock.patch("udata.linkchecker.checker.get_linkchecker")
79
79
  def test_check_resource_filter_result(self, mock_fn):
80
- check_res = {'check:status': 200, 'dummy': 'dummy'}
80
+ check_res = {"check:status": 200, "dummy": "dummy"}
81
81
 
82
82
  class DummyLinkchecker:
83
83
  def check(self, _):
84
84
  return check_res
85
+
85
86
  mock_fn.return_value = DummyLinkchecker
86
87
 
87
88
  res = check_resource(self.resource)
88
89
  self.assertEqual(res, check_res)
89
- self.assertNotIn('dummy', self.resource.extras)
90
+ self.assertNotIn("dummy", self.resource.extras)
90
91
 
91
- @mock.patch('udata.linkchecker.checker.get_linkchecker')
92
+ @mock.patch("udata.linkchecker.checker.get_linkchecker")
92
93
  def test_check_resource_linkchecker_no_status(self, mock_fn):
93
94
  class DummyLinkchecker:
94
95
  def check(self, _):
95
- return {'check:available': True}
96
+ return {"check:available": True}
97
+
96
98
  mock_fn.return_value = DummyLinkchecker
97
99
  res = check_resource(self.resource)
98
- self.assertEqual(res,
99
- ({'error': 'No status in response from linkchecker'},
100
- 503))
100
+ self.assertEqual(res, ({"error": "No status in response from linkchecker"}, 503))
101
101
 
102
- @mock.patch('udata.linkchecker.checker.get_linkchecker')
102
+ @mock.patch("udata.linkchecker.checker.get_linkchecker")
103
103
  def test_check_resource_linkchecker_check_error(self, mock_fn):
104
104
  class DummyLinkchecker:
105
105
  def check(self, _):
106
- return {'check:error': 'ERROR'}
106
+ return {"check:error": "ERROR"}
107
+
107
108
  mock_fn.return_value = DummyLinkchecker
108
109
  res = check_resource(self.resource)
109
- self.assertEqual(res, ({'error': 'ERROR'}, 500))
110
+ self.assertEqual(res, ({"error": "ERROR"}, 500))
110
111
 
111
- @mock.patch('udata.linkchecker.checker.get_linkchecker')
112
+ @mock.patch("udata.linkchecker.checker.get_linkchecker")
112
113
  def test_check_resource_linkchecker_in_resource(self, mock_fn):
113
- self.resource.extras['check:checker'] = 'another_linkchecker'
114
+ self.resource.extras["check:checker"] = "another_linkchecker"
114
115
  self.resource.save()
115
116
  check_resource(self.resource)
116
117
  args, kwargs = mock_fn.call_args
117
- self.assertEqual(args, ('another_linkchecker', ))
118
+ self.assertEqual(args, ("another_linkchecker",))
118
119
 
119
120
  def test_check_resource_linkchecker_no_check(self):
120
- self.resource.extras['check:checker'] = 'no_check'
121
+ self.resource.extras["check:checker"] = "no_check"
121
122
  self.resource.save()
122
123
  res = check_resource(self.resource)
123
- self.assertEqual(res.get('check:status'), 204)
124
- self.assertEqual(res.get('check:available'), True)
124
+ self.assertEqual(res.get("check:status"), 204)
125
+ self.assertEqual(res.get("check:available"), True)
125
126
 
126
127
  def test_check_resource_ignored_domain(self):
127
128
  self.resource.extras = {}
128
- self.resource.url = 'http://example-ignore.com/url'
129
+ self.resource.url = "http://example-ignore.com/url"
129
130
  self.resource.save()
130
131
  res = check_resource(self.resource)
131
- self.assertEqual(res.get('check:status'), 204)
132
- self.assertEqual(res.get('check:available'), True)
132
+ self.assertEqual(res.get("check:status"), 204)
133
+ self.assertEqual(res.get("check:available"), True)
133
134
 
134
135
  def test_check_resource_ignored_pattern(self):
135
136
  self.resource.extras = {}
136
- self.resource.url = 'http://example.com/url?format=shp'
137
+ self.resource.url = "http://example.com/url?format=shp"
137
138
  self.resource.save()
138
139
  res = check_resource(self.resource)
139
- self.assertEqual(res.get('check:status'), 204)
140
- self.assertEqual(res.get('check:available'), True)
140
+ self.assertEqual(res.get("check:status"), 204)
141
+ self.assertEqual(res.get("check:available"), True)
141
142
 
142
143
  def test_is_need_check(self):
143
- self.resource.extras = {'check:available': True,
144
- 'check:date': datetime.utcnow(),
145
- 'check:status': 42}
144
+ self.resource.extras = {
145
+ "check:available": True,
146
+ "check:date": datetime.utcnow(),
147
+ "check:status": 42,
148
+ }
146
149
  self.assertFalse(self.resource.need_check())
147
150
 
148
151
  def test_is_need_check_unknown_status(self):
@@ -151,56 +154,56 @@ class LinkcheckerTest(TestCase):
151
154
 
152
155
  def test_is_need_check_cache_expired(self):
153
156
  self.resource.extras = {
154
- 'check:available': True,
155
- 'check:date': datetime.utcnow() - timedelta(seconds=3600),
156
- 'check:status': 42
157
+ "check:available": True,
158
+ "check:date": datetime.utcnow() - timedelta(seconds=3600),
159
+ "check:status": 42,
157
160
  }
158
161
  self.assertTrue(self.resource.need_check())
159
162
 
160
163
  def test_is_need_check_date_string(self):
161
164
  check_date = (datetime.utcnow() - timedelta(seconds=3600)).isoformat()
162
165
  self.resource.extras = {
163
- 'check:available': True,
164
- 'check:date': check_date,
165
- 'check:status': 42
166
+ "check:available": True,
167
+ "check:date": check_date,
168
+ "check:status": 42,
166
169
  }
167
170
  self.assertTrue(self.resource.need_check())
168
171
 
169
172
  def test_is_need_check_wrong_check_date(self):
170
- check_date = '123azerty'
173
+ check_date = "123azerty"
171
174
  self.resource.extras = {
172
- 'check:available': True,
173
- 'check:date': check_date,
174
- 'check:status': 42
175
+ "check:available": True,
176
+ "check:date": check_date,
177
+ "check:status": 42,
175
178
  }
176
179
  self.assertTrue(self.resource.need_check())
177
180
 
178
181
  def test_is_need_check_wrong_check_date_int(self):
179
182
  check_date = 42
180
183
  self.resource.extras = {
181
- 'check:available': True,
182
- 'check:date': check_date,
183
- 'check:status': 42
184
+ "check:available": True,
185
+ "check:date": check_date,
186
+ "check:status": 42,
184
187
  }
185
188
  self.assertTrue(self.resource.need_check())
186
189
 
187
190
  def test_is_need_check_count_availability(self):
188
191
  self.resource.extras = {
189
192
  # should need a new check after 100 * 30s = 3000s < 3600s
190
- 'check:count-availability': 100,
191
- 'check:available': True,
192
- 'check:date': datetime.utcnow() - timedelta(seconds=3600),
193
- 'check:status': 42
193
+ "check:count-availability": 100,
194
+ "check:available": True,
195
+ "check:date": datetime.utcnow() - timedelta(seconds=3600),
196
+ "check:status": 42,
194
197
  }
195
198
  self.assertTrue(self.resource.need_check())
196
199
 
197
200
  def test_is_need_check_count_availability_expired(self):
198
201
  self.resource.extras = {
199
202
  # should need a new check after 150 * 30s = 4500s > 3600s
200
- 'check:count-availability': 150,
201
- 'check:available': True,
202
- 'check:date': datetime.utcnow() - timedelta(seconds=3600),
203
- 'check:status': 42
203
+ "check:count-availability": 150,
204
+ "check:available": True,
205
+ "check:date": datetime.utcnow() - timedelta(seconds=3600),
206
+ "check:status": 42,
204
207
  }
205
208
  self.assertFalse(self.resource.need_check())
206
209
 
@@ -208,64 +211,67 @@ class LinkcheckerTest(TestCase):
208
211
  self.resource.extras = {
209
212
  # should need a new check after 30s < 3600S
210
213
  # count-availability is below threshold
211
- 'check:count-availability': 95,
212
- 'check:available': False,
213
- 'check:date': datetime.utcnow() - timedelta(seconds=3600),
214
- 'check:status': 42
214
+ "check:count-availability": 95,
215
+ "check:available": False,
216
+ "check:date": datetime.utcnow() - timedelta(seconds=3600),
217
+ "check:status": 42,
215
218
  }
216
219
  self.assertTrue(self.resource.need_check())
217
220
 
218
- @mock.patch('udata.linkchecker.checker.get_linkchecker')
221
+ @mock.patch("udata.linkchecker.checker.get_linkchecker")
219
222
  def test_count_availability_increment(self, mock_fn):
220
- check_res = {'check:status': 200, 'check:available': True,
221
- 'check:date': datetime.utcnow()}
223
+ check_res = {"check:status": 200, "check:available": True, "check:date": datetime.utcnow()}
222
224
 
223
225
  class DummyLinkchecker:
224
226
  def check(self, _):
225
227
  return check_res
228
+
226
229
  mock_fn.return_value = DummyLinkchecker
227
230
 
228
231
  check_resource(self.resource)
229
- self.assertEqual(self.resource.extras['check:count-availability'], 1)
232
+ self.assertEqual(self.resource.extras["check:count-availability"], 1)
230
233
 
231
234
  check_resource(self.resource)
232
- self.assertEqual(self.resource.extras['check:count-availability'], 2)
235
+ self.assertEqual(self.resource.extras["check:count-availability"], 2)
233
236
 
234
- @mock.patch('udata.linkchecker.checker.get_linkchecker')
237
+ @mock.patch("udata.linkchecker.checker.get_linkchecker")
235
238
  def test_count_availability_reset(self, mock_fn):
236
- self.resource.extras = {'check:status': 200, 'check:available': True,
237
- 'check:date': datetime.utcnow(),
238
- 'check:count-availability': 2}
239
- check_res = {'check:status': 200, 'check:available': False,
240
- 'check:date': datetime.utcnow()}
239
+ self.resource.extras = {
240
+ "check:status": 200,
241
+ "check:available": True,
242
+ "check:date": datetime.utcnow(),
243
+ "check:count-availability": 2,
244
+ }
245
+ check_res = {"check:status": 200, "check:available": False, "check:date": datetime.utcnow()}
241
246
 
242
247
  class DummyLinkchecker:
243
248
  def check(self, _):
244
249
  return check_res
250
+
245
251
  mock_fn.return_value = DummyLinkchecker
246
252
 
247
253
  check_resource(self.resource)
248
- self.assertEqual(self.resource.extras['check:count-availability'], 1)
254
+ self.assertEqual(self.resource.extras["check:count-availability"], 1)
249
255
 
250
256
  def test_count_availability_threshold(self):
251
257
  self.resource.extras = {
252
- 'check:status': 404,
253
- 'check:available': False,
258
+ "check:status": 404,
259
+ "check:available": False,
254
260
  # if it weren't above threshold, should need check (>30s)
255
261
  # and we're still below max_cache 101 * 0.5 < 100
256
- 'check:date': datetime.utcnow() - timedelta(seconds=60),
257
- 'check:count-availability': 101
262
+ "check:date": datetime.utcnow() - timedelta(seconds=60),
263
+ "check:count-availability": 101,
258
264
  }
259
265
  self.assertFalse(self.resource.need_check())
260
266
 
261
267
  def test_count_availability_max_cache_duration(self):
262
268
  self.resource.extras = {
263
- 'check:status': 200,
264
- 'check:available': True,
269
+ "check:status": 200,
270
+ "check:available": True,
265
271
  # next check should be at 300 * 0.5 = 150min
266
272
  # but we are above max cache duration 150min > 100min
267
273
  # and 120m > 100 min so we should need a new check
268
- 'check:date': datetime.utcnow() - timedelta(minutes=120),
269
- 'check:count-availability': 300
274
+ "check:date": datetime.utcnow() - timedelta(minutes=120),
275
+ "check:count-availability": 300,
270
276
  }
271
277
  self.assertTrue(self.resource.need_check())
udata/tests/test_mail.py CHANGED
@@ -4,25 +4,21 @@ from smtplib import SMTPRecipientsRefused
4
4
  import pytest
5
5
 
6
6
  from udata.core.user.factories import UserFactory
7
- from udata.mail import send, mail_sent
8
- from udata.tests import TestCase, DBTestMixin
7
+ from udata.mail import mail_sent, send
8
+ from udata.tests import DBTestMixin, TestCase
9
9
  from udata.tests.helpers import assert_emit, assert_not_emit
10
10
 
11
+ SMTPRecipientsRefusedList = ["not-found@udata", "not-found-either@udata"]
11
12
 
12
- SMTPRecipientsRefusedList = [
13
- 'not-found@udata',
14
- 'not-found-either@udata'
15
- ]
16
13
 
17
-
18
- class FakeSender():
14
+ class FakeSender:
19
15
  def send(self, msg):
20
16
  if all(recipient in SMTPRecipientsRefusedList for recipient in msg.recipients):
21
17
  raise SMTPRecipientsRefused(msg.recipients)
22
18
  mail_sent.send(msg)
23
19
 
24
20
 
25
- class FakeMail():
21
+ class FakeMail:
26
22
  @contextmanager
27
23
  def connect(*args, **kw):
28
24
  yield FakeSender()
@@ -31,26 +27,26 @@ class FakeMail():
31
27
  class MailSendTest(TestCase, DBTestMixin):
32
28
  def create_app(self):
33
29
  app = super().create_app()
34
- app.config['SEND_MAIL'] = True
30
+ app.config["SEND_MAIL"] = True
35
31
  return app
36
32
 
37
33
  @pytest.fixture(autouse=True)
38
34
  def patch_mail(self, mocker):
39
- mocker.patch('udata.mail.mail', FakeMail())
35
+ mocker.patch("udata.mail.mail", FakeMail())
40
36
 
41
37
  def test_send_mail(self):
42
38
  with assert_emit(mail_sent):
43
- send('subject', [UserFactory(email='recipient@udata')], 'base')
39
+ send("subject", [UserFactory(email="recipient@udata")], "base")
44
40
 
45
41
  def test_send_mail_to_not_found_recipients(self):
46
42
  with assert_not_emit(mail_sent):
47
- send('subject', [UserFactory(email='not-found@udata')], 'base')
43
+ send("subject", [UserFactory(email="not-found@udata")], "base")
48
44
 
49
45
  def test_send_mail_to_multiple_recipients_with_some_not_found(self):
50
46
  recipients = [
51
- UserFactory(email='not-found@udata'),
52
- UserFactory(email='recipient@udata'),
53
- UserFactory(email='not-found-either@udata')
47
+ UserFactory(email="not-found@udata"),
48
+ UserFactory(email="recipient@udata"),
49
+ UserFactory(email="not-found-either@udata"),
54
50
  ]
55
51
  with assert_emit(mail_sent):
56
- send('subject', recipients, 'base')
52
+ send("subject", recipients, "base")