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
@@ -1,9 +1,7 @@
1
1
  import pytest
2
-
3
2
  from flask import url_for
4
-
5
- from rdflib import URIRef, Literal, Graph
6
- from rdflib.namespace import RDF, FOAF
3
+ from rdflib import Graph, Literal, URIRef
4
+ from rdflib.namespace import FOAF, RDF
7
5
  from rdflib.resource import Resource
8
6
 
9
7
  from udata.core.dataservices.factories import DataserviceFactory, HarvestMetadataFactory
@@ -16,17 +14,15 @@ from udata.core.user.factories import UserFactory
16
14
  from udata.rdf import CONTEXT, DCAT, DCT, HYDRA
17
15
  from udata.tests.helpers import assert200, assert404, assert_redirects
18
16
 
19
-
20
- pytestmark = pytest.mark.usefixtures('clean_db')
17
+ pytestmark = pytest.mark.usefixtures("clean_db")
21
18
 
22
19
 
23
20
  @pytest.mark.frontend
24
21
  class CatalogTest:
25
-
26
22
  def test_minimal(self, app):
27
23
  site = SiteFactory()
28
- home_url = url_for('api.site', _external=True)
29
- uri = url_for('api.site_rdf_catalog', _external=True)
24
+ home_url = url_for("api.site", _external=True)
25
+ uri = url_for("api.site_rdf_catalog", _external=True)
30
26
  datasets = DatasetFactory.create_batch(3)
31
27
  catalog = build_catalog(site, datasets)
32
28
  graph = catalog.graph
@@ -41,7 +37,7 @@ class CatalogTest:
41
37
  assert str(catalog.identifier) == uri
42
38
  assert catalog.value(DCT.title) == Literal(site.title)
43
39
  assert catalog.value(DCT.description) == Literal(f"{site.title}")
44
- lang = app.config['DEFAULT_LANGUAGE']
40
+ lang = app.config["DEFAULT_LANGUAGE"]
45
41
  assert catalog.value(DCT.language) == Literal(lang)
46
42
 
47
43
  assert len(list(catalog.objects(DCAT.dataset))) == len(datasets)
@@ -50,7 +46,7 @@ class CatalogTest:
50
46
 
51
47
  org = catalog.value(DCT.publisher)
52
48
  assert org.value(RDF.type).identifier == FOAF.Organization
53
- assert org.value(FOAF.name) == Literal(app.config['SITE_AUTHOR'])
49
+ assert org.value(FOAF.name) == Literal(app.config["SITE_AUTHOR"])
54
50
 
55
51
  graph = catalog.graph
56
52
  graph_datasets = graph.subjects(RDF.type, DCAT.Dataset)
@@ -78,16 +74,26 @@ class CatalogTest:
78
74
  site = SiteFactory()
79
75
  page_size = 3
80
76
  total = 4
81
- uri = url_for('api.site_rdf_catalog', _external=True)
82
- uri_first = url_for('api.site_rdf_catalog_format', format='json',
83
- page=1, page_size=page_size, _external=True)
84
- uri_last = url_for('api.site_rdf_catalog_format', format='json',
85
- page=2, page_size=page_size, _external=True)
77
+ uri = url_for("api.site_rdf_catalog", _external=True)
78
+ uri_first = url_for(
79
+ "api.site_rdf_catalog_format",
80
+ format="json",
81
+ page=1,
82
+ page_size=page_size,
83
+ _external=True,
84
+ )
85
+ uri_last = url_for(
86
+ "api.site_rdf_catalog_format",
87
+ format="json",
88
+ page=2,
89
+ page_size=page_size,
90
+ _external=True,
91
+ )
86
92
  DatasetFactory.create_batch(total)
87
93
 
88
94
  # First page
89
95
  datasets = Dataset.objects.paginate(1, page_size)
90
- catalog = build_catalog(site, datasets, format='json')
96
+ catalog = build_catalog(site, datasets, format="json")
91
97
  graph = catalog.graph
92
98
 
93
99
  assert isinstance(catalog, Resource)
@@ -100,8 +106,7 @@ class CatalogTest:
100
106
 
101
107
  assert len(list(catalog.objects(DCAT.dataset))) == page_size
102
108
 
103
- paginations = list(graph.subjects(RDF.type,
104
- HYDRA.PartialCollectionView))
109
+ paginations = list(graph.subjects(RDF.type, HYDRA.PartialCollectionView))
105
110
  assert len(paginations) == 1
106
111
  pagination = graph.resource(paginations[0])
107
112
  assert pagination.identifier == URIRef(uri_first)
@@ -112,7 +117,7 @@ class CatalogTest:
112
117
 
113
118
  # Second page
114
119
  datasets = Dataset.objects.paginate(2, page_size)
115
- catalog = build_catalog(site, datasets, format='json')
120
+ catalog = build_catalog(site, datasets, format="json")
116
121
  graph = catalog.graph
117
122
 
118
123
  assert isinstance(catalog, Resource)
@@ -125,8 +130,7 @@ class CatalogTest:
125
130
 
126
131
  assert len(list(catalog.objects(DCAT.dataset))) == 1
127
132
 
128
- paginations = list(graph.subjects(RDF.type,
129
- HYDRA.PartialCollectionView))
133
+ paginations = list(graph.subjects(RDF.type, HYDRA.PartialCollectionView))
130
134
  assert len(paginations) == 1
131
135
  pagination = graph.resource(paginations[0])
132
136
  assert pagination.identifier == URIRef(uri_last)
@@ -138,128 +142,132 @@ class CatalogTest:
138
142
 
139
143
  @pytest.mark.frontend
140
144
  class SiteRdfViewsTest:
141
-
142
145
  def test_expose_jsonld_context(self, client):
143
- url = url_for('api.site_jsonld_context')
144
- assert url == '/api/1/site/context.jsonld'
146
+ url = url_for("api.site_jsonld_context")
147
+ assert url == "/api/1/site/context.jsonld"
145
148
 
146
- response = client.get(url, headers={'Accept': 'application/ld+json'})
149
+ response = client.get(url, headers={"Accept": "application/ld+json"})
147
150
  assert200(response)
148
- assert response.content_type == 'application/ld+json'
151
+ assert response.content_type == "application/ld+json"
149
152
  assert response.json == CONTEXT
150
153
 
151
154
  def test_catalog_default_to_jsonld(self, client):
152
- expected = url_for('api.site_rdf_catalog_format', format='json')
153
- response = client.get(url_for('api.site_rdf_catalog'))
155
+ expected = url_for("api.site_rdf_catalog_format", format="json")
156
+ response = client.get(url_for("api.site_rdf_catalog"))
154
157
  assert_redirects(response, expected)
155
158
 
156
159
  def test_rdf_perform_content_negociation(self, client):
157
- expected = url_for('api.site_rdf_catalog_format', format='xml')
158
- url = url_for('api.site_rdf_catalog')
159
- headers = {'accept': 'application/xml'}
160
+ expected = url_for("api.site_rdf_catalog_format", format="xml")
161
+ url = url_for("api.site_rdf_catalog")
162
+ headers = {"accept": "application/xml"}
160
163
  response = client.get(url, headers=headers)
161
164
  assert_redirects(response, expected)
162
165
 
163
- @pytest.mark.parametrize('fmt', ('json', 'jsonld'))
166
+ @pytest.mark.parametrize("fmt", ("json", "jsonld"))
164
167
  def test_catalog_rdf_json_ld(self, fmt, client):
165
- url = url_for('api.site_rdf_catalog_format', format=fmt)
166
- response = client.get(url, headers={'Accept': 'application/ld+json'})
168
+ url = url_for("api.site_rdf_catalog_format", format=fmt)
169
+ response = client.get(url, headers={"Accept": "application/ld+json"})
167
170
  assert200(response)
168
- assert response.content_type == 'application/ld+json'
169
- assert response.json['@context']['@vocab'] == 'http://www.w3.org/ns/dcat#'
171
+ assert response.content_type == "application/ld+json"
172
+ assert response.json["@context"]["@vocab"] == "http://www.w3.org/ns/dcat#"
170
173
 
171
174
  def test_catalog_rdf_n3(self, client):
172
- url = url_for('api.site_rdf_catalog_format', format='n3')
173
- response = client.get(url, headers={'Accept': 'text/n3'})
175
+ url = url_for("api.site_rdf_catalog_format", format="n3")
176
+ response = client.get(url, headers={"Accept": "text/n3"})
174
177
  assert200(response)
175
- assert response.content_type == 'text/n3'
178
+ assert response.content_type == "text/n3"
176
179
 
177
180
  def test_catalog_rdf_turtle(self, client):
178
- url = url_for('api.site_rdf_catalog_format', format='ttl')
179
- response = client.get(url, headers={'Accept': 'application/x-turtle'})
181
+ url = url_for("api.site_rdf_catalog_format", format="ttl")
182
+ response = client.get(url, headers={"Accept": "application/x-turtle"})
180
183
  assert200(response)
181
- assert response.content_type == 'application/x-turtle'
184
+ assert response.content_type == "application/x-turtle"
182
185
 
183
- @pytest.mark.parametrize('fmt', ('xml', 'rdf', 'owl'))
186
+ @pytest.mark.parametrize("fmt", ("xml", "rdf", "owl"))
184
187
  def test_catalog_rdf_rdfxml(self, fmt, client):
185
- url = url_for('api.site_rdf_catalog_format', format=fmt)
186
- response = client.get(url, headers={'Accept': 'application/rdf+xml'})
188
+ url = url_for("api.site_rdf_catalog_format", format=fmt)
189
+ response = client.get(url, headers={"Accept": "application/rdf+xml"})
187
190
  assert200(response)
188
- assert response.content_type == 'application/rdf+xml'
191
+ assert response.content_type == "application/rdf+xml"
189
192
 
190
193
  def test_catalog_rdf_n_triples(self, client):
191
- url = url_for('api.site_rdf_catalog_format', format='nt')
192
- response = client.get(url, headers={'Accept': 'application/n-triples'})
194
+ url = url_for("api.site_rdf_catalog_format", format="nt")
195
+ response = client.get(url, headers={"Accept": "application/n-triples"})
193
196
  assert200(response)
194
- assert response.content_type == 'application/n-triples'
197
+ assert response.content_type == "application/n-triples"
195
198
 
196
199
  def test_catalog_rdf_trig(self, client):
197
- url = url_for('api.site_rdf_catalog_format', format='trig')
198
- response = client.get(url, headers={'Accept': 'application/trig'})
200
+ url = url_for("api.site_rdf_catalog_format", format="trig")
201
+ response = client.get(url, headers={"Accept": "application/trig"})
199
202
  assert200(response)
200
- assert response.content_type == 'application/trig'
203
+ assert response.content_type == "application/trig"
201
204
 
202
- @pytest.mark.parametrize('fmt', ('json', 'xml', 'ttl'))
205
+ @pytest.mark.parametrize("fmt", ("json", "xml", "ttl"))
203
206
  def test_dataportal_compliance(self, fmt, client):
204
- url = url_for('api.site_dataportal', format=fmt)
205
- assert url == '/api/1/site/data.{0}'.format(fmt)
206
- expected_url = url_for('api.site_rdf_catalog_format', format=fmt)
207
+ url = url_for("api.site_dataportal", format=fmt)
208
+ assert url == "/api/1/site/data.{0}".format(fmt)
209
+ expected_url = url_for("api.site_rdf_catalog_format", format=fmt)
207
210
 
208
211
  response = client.get(url)
209
212
  assert_redirects(response, expected_url)
210
213
 
211
214
  def test_catalog_rdf_paginate(self, client):
212
215
  DatasetFactory.create_batch(4)
213
- url = url_for('api.site_rdf_catalog_format', format='n3', page_size=3)
214
- next_url = url_for('api.site_rdf_catalog_format', format='n3',
215
- page=2, page_size=3, _external=True)
216
+ url = url_for("api.site_rdf_catalog_format", format="n3", page_size=3)
217
+ next_url = url_for(
218
+ "api.site_rdf_catalog_format", format="n3", page=2, page_size=3, _external=True
219
+ )
216
220
 
217
- response = client.get(url, headers={'Accept': 'text/n3'})
221
+ response = client.get(url, headers={"Accept": "text/n3"})
218
222
  assert200(response)
219
223
 
220
- graph = Graph().parse(data=response.data, format='n3')
221
- pagination = graph.value(predicate=RDF.type,
222
- object=HYDRA.PartialCollectionView)
224
+ graph = Graph().parse(data=response.data, format="n3")
225
+ pagination = graph.value(predicate=RDF.type, object=HYDRA.PartialCollectionView)
223
226
  assert pagination is not None
224
227
  pagination = graph.resource(pagination)
225
228
  assert not pagination.value(HYDRA.previous)
226
229
  assert pagination.value(HYDRA.next).identifier == URIRef(next_url)
227
230
 
228
231
  def test_catalog_format_unknown(self, client):
229
- url = url_for('api.site_rdf_catalog_format', format='unknown')
232
+ url = url_for("api.site_rdf_catalog_format", format="unknown")
230
233
  response = client.get(url)
231
234
  assert404(response)
232
235
 
233
236
  def test_catalog_rdf_filter_tag(self, client):
234
- DatasetFactory.create_batch(4, tags=['my-tag'])
237
+ DatasetFactory.create_batch(4, tags=["my-tag"])
235
238
  DatasetFactory.create_batch(3)
236
- url = url_for('api.site_rdf_catalog_format', format='xml', tag='my-tag')
239
+ url = url_for("api.site_rdf_catalog_format", format="xml", tag="my-tag")
237
240
 
238
- response = client.get(url, headers={'Accept': 'application/xml'})
241
+ response = client.get(url, headers={"Accept": "application/xml"})
239
242
  assert200(response)
240
243
 
241
- graph = Graph().parse(data=response.data, format='xml')
244
+ graph = Graph().parse(data=response.data, format="xml")
242
245
 
243
246
  datasets = list(graph.subjects(RDF.type, DCAT.Dataset))
244
247
  assert len(datasets) == 4
245
248
 
246
249
  for dat in datasets:
247
- assert graph.value(dat, DCAT.keyword) == Literal('my-tag')
250
+ assert graph.value(dat, DCAT.keyword) == Literal("my-tag")
248
251
 
249
252
  def test_catalog_rdf_dataservices(self, client):
250
253
  dataset_a = DatasetFactory.create()
251
254
  dataset_b = DatasetFactory.create()
252
255
  dataset_c = DatasetFactory.create()
253
256
 
254
- dataservice_a = DataserviceFactory.create(datasets=[dataset_a.id], harvest=HarvestMetadataFactory())
257
+ dataservice_a = DataserviceFactory.create(
258
+ datasets=[dataset_a.id], harvest=HarvestMetadataFactory()
259
+ )
255
260
  dataservice_b = DataserviceFactory.create(datasets=[dataset_b.id])
256
261
  dataservice_x = DataserviceFactory.create(datasets=[dataset_a.id, dataset_c.id])
257
262
  dataservice_y = DataserviceFactory.create(datasets=[])
258
263
 
259
- response = client.get(url_for('api.site_rdf_catalog_format', format='xml'), headers={'Accept': 'application/xml'})
264
+ response = client.get(
265
+ url_for("api.site_rdf_catalog_format", format="xml"),
266
+ headers={"Accept": "application/xml"},
267
+ )
260
268
  assert200(response)
261
269
 
262
- graph = Graph().parse(data=response.data, format='xml')
270
+ graph = Graph().parse(data=response.data, format="xml")
263
271
 
264
272
  datasets = list(graph.subjects(RDF.type, DCAT.Dataset))
265
273
  assert len(datasets) == 3
@@ -268,10 +276,13 @@ class SiteRdfViewsTest:
268
276
  assert len(dataservices) == 4
269
277
 
270
278
  # Test first page contains the dataservice without dataset
271
- response = client.get(url_for('api.site_rdf_catalog_format', format='xml', page_size=1), headers={'Accept': 'application/xml'})
279
+ response = client.get(
280
+ url_for("api.site_rdf_catalog_format", format="xml", page_size=1),
281
+ headers={"Accept": "application/xml"},
282
+ )
272
283
  assert200(response)
273
284
 
274
- graph = Graph().parse(data=response.data, format='xml')
285
+ graph = Graph().parse(data=response.data, format="xml")
275
286
 
276
287
  datasets = list(graph.subjects(RDF.type, DCAT.Dataset))
277
288
  assert len(datasets) == 1
@@ -279,13 +290,18 @@ class SiteRdfViewsTest:
279
290
 
280
291
  dataservices = list(graph.subjects(RDF.type, DCAT.DataService))
281
292
  assert len(dataservices) == 2
282
- assert sorted([str(d.id) for d in [dataservice_x, dataservice_y]]) == sorted([str(graph.value(d, DCT.identifier)) for d in dataservices])
293
+ assert sorted([str(d.id) for d in [dataservice_x, dataservice_y]]) == sorted(
294
+ [str(graph.value(d, DCT.identifier)) for d in dataservices]
295
+ )
283
296
 
284
297
  # Test second page doesn't contains the dataservice without dataset
285
- response = client.get(url_for('api.site_rdf_catalog_format', format='xml', page_size=1, page=2), headers={'Accept': 'application/xml'})
298
+ response = client.get(
299
+ url_for("api.site_rdf_catalog_format", format="xml", page_size=1, page=2),
300
+ headers={"Accept": "application/xml"},
301
+ )
286
302
  assert200(response)
287
303
 
288
- graph = Graph().parse(data=response.data, format='xml')
304
+ graph = Graph().parse(data=response.data, format="xml")
289
305
 
290
306
  datasets = list(graph.subjects(RDF.type, DCAT.Dataset))
291
307
  assert len(datasets) == 1
@@ -1,8 +1,8 @@
1
- from udata.models import db, Activity
2
- from udata.tests import TestCase, DBTestMixin, WebTestMixin
3
- from udata.core.user.factories import UserFactory
4
- from udata.core.organization.factories import OrganizationFactory
5
1
  from udata.auth import login_user
2
+ from udata.core.organization.factories import OrganizationFactory
3
+ from udata.core.user.factories import UserFactory
4
+ from udata.models import Activity, db
5
+ from udata.tests import DBTestMixin, TestCase, WebTestMixin
6
6
 
7
7
 
8
8
  class FakeSubject(db.Document):
@@ -10,13 +10,13 @@ class FakeSubject(db.Document):
10
10
 
11
11
 
12
12
  class FakeActivity(Activity):
13
- key = 'fake'
13
+ key = "fake"
14
14
  related_to = db.ReferenceField(FakeSubject)
15
15
 
16
16
 
17
17
  class ActivityTest(WebTestMixin, DBTestMixin, TestCase):
18
18
  def setUp(self):
19
- self.fake = FakeSubject.objects.create(name='fake')
19
+ self.fake = FakeSubject.objects.create(name="fake")
20
20
  self.login()
21
21
 
22
22
  def test_create_and_retrieve_for_user(self):
@@ -28,21 +28,22 @@ class ActivityTest(WebTestMixin, DBTestMixin, TestCase):
28
28
  self.assertIsInstance(activities[0], FakeActivity)
29
29
 
30
30
  def test_create_and_retrieve_with_extras(self):
31
- FakeActivity.objects.create(actor=self.user, related_to=self.fake, extras={'some_key': 'some_value',
32
- 'other_key': 'other_value'})
31
+ FakeActivity.objects.create(
32
+ actor=self.user,
33
+ related_to=self.fake,
34
+ extras={"some_key": "some_value", "other_key": "other_value"},
35
+ )
33
36
 
34
37
  activities = Activity.objects(actor=self.user)
35
38
 
36
39
  self.assertEqual(len(activities), 1)
37
- self.assertEqual(activities[0].extras['some_key'], 'some_value')
38
- self.assertEqual(activities[0].extras['other_key'], 'other_value')
40
+ self.assertEqual(activities[0].extras["some_key"], "some_value")
41
+ self.assertEqual(activities[0].extras["other_key"], "other_value")
39
42
  self.assertIsInstance(activities[0], FakeActivity)
40
43
 
41
-
42
44
  def test_create_and_retrieve_for_org(self):
43
45
  org = OrganizationFactory()
44
- FakeActivity.objects.create(
45
- actor=self.user, related_to=self.fake, organization=org)
46
+ FakeActivity.objects.create(actor=self.user, related_to=self.fake, organization=org)
46
47
 
47
48
  activities = Activity.objects(organization=org)
48
49
 
@@ -51,8 +52,7 @@ class ActivityTest(WebTestMixin, DBTestMixin, TestCase):
51
52
 
52
53
  def test_create_and_retrieve_for_related(self):
53
54
  org = OrganizationFactory()
54
- FakeActivity.objects.create(
55
- actor=self.user, related_to=self.fake, organization=org)
55
+ FakeActivity.objects.create(actor=self.user, related_to=self.fake, organization=org)
56
56
  FakeActivity.objects.create(actor=UserFactory(), related_to=self.fake)
57
57
 
58
58
  activities = Activity.objects(related_to=self.fake)
@@ -67,7 +67,7 @@ class ActivityTest(WebTestMixin, DBTestMixin, TestCase):
67
67
  self.emitted = True
68
68
 
69
69
  def test_emit_signal(self):
70
- '''It should emit a signal on new activity'''
70
+ """It should emit a signal on new activity"""
71
71
  self.emitted = False
72
72
  with FakeActivity.on_new.connected_to(self.check_emitted):
73
73
  FakeActivity.objects.create(actor=self.user, related_to=self.fake)
@@ -75,7 +75,7 @@ class ActivityTest(WebTestMixin, DBTestMixin, TestCase):
75
75
  self.assertTrue(self.emitted)
76
76
 
77
77
  def test_class_shortcut(self):
78
- '''It should emit a signal on new activity'''
78
+ """It should emit a signal on new activity"""
79
79
  self.emitted = False
80
80
  self.login()
81
81
  with self.app.app_context():
@@ -0,0 +1,62 @@
1
+ from datetime import datetime
2
+
3
+ import pytest
4
+ from flask import url_for
5
+
6
+ from udata.core.dataset.factories import DatasetFactory
7
+ from udata.core.topic.factories import TopicFactory
8
+ from udata.search import reindex
9
+ from udata.tests.api import APITestCase
10
+ from udata.tests.helpers import assert_status
11
+
12
+
13
+ class CorsTest(APITestCase):
14
+ modules = []
15
+
16
+ def test_cors_redirects(self):
17
+ dataset = DatasetFactory(title="Old title")
18
+ old_slug = dataset.slug
19
+
20
+ # New slug to force a redirect from old slug
21
+ dataset.title = "New title"
22
+ dataset.save()
23
+
24
+ response = self.get(url_for("api.dataset", dataset=old_slug))
25
+ assert_status(response, 308)
26
+
27
+ response = self.options(
28
+ url_for("api.dataset", dataset=old_slug),
29
+ headers={
30
+ "Origin": "http://localhost",
31
+ "Access-Control-Request-Method": "GET",
32
+ },
33
+ )
34
+ assert_status(response, 204)
35
+
36
+ def test_cors_404(self):
37
+ response = self.get(url_for("api.dataset", dataset="unknown-dataset"))
38
+ assert_status(response, 404)
39
+
40
+ response = self.options(
41
+ url_for("api.dataset", dataset="unknown-dataset"),
42
+ headers={
43
+ "Origin": "http://localhost",
44
+ "Access-Control-Request-Method": "GET",
45
+ },
46
+ )
47
+ assert_status(response, 204)
48
+
49
+ def test_cors_410_with_api_abort(self):
50
+ dataset = DatasetFactory(deleted=datetime.now())
51
+
52
+ response = self.get(url_for("api.dataset", dataset=dataset.id))
53
+ assert_status(response, 410)
54
+
55
+ response = self.options(
56
+ url_for("api.dataset", dataset=dataset.id),
57
+ headers={
58
+ "Origin": "http://localhost",
59
+ "Access-Control-Request-Method": "GET",
60
+ },
61
+ )
62
+ assert_status(response, 204)