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

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

Potentially problematic release.


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

Files changed (425) hide show
  1. tasks/__init__.py +109 -107
  2. tasks/helpers.py +18 -18
  3. udata/__init__.py +4 -4
  4. udata/admin/views.py +5 -5
  5. udata/api/__init__.py +135 -124
  6. udata/api/commands.py +45 -37
  7. udata/api/errors.py +5 -4
  8. udata/api/fields.py +23 -21
  9. udata/api/oauth2.py +55 -74
  10. udata/api/parsers.py +15 -15
  11. udata/api/signals.py +1 -1
  12. udata/api_fields.py +137 -89
  13. udata/app.py +56 -54
  14. udata/assets.py +5 -5
  15. udata/auth/__init__.py +37 -26
  16. udata/auth/forms.py +23 -15
  17. udata/auth/helpers.py +1 -1
  18. udata/auth/mails.py +3 -3
  19. udata/auth/password_validation.py +19 -15
  20. udata/auth/views.py +94 -68
  21. udata/commands/__init__.py +71 -69
  22. udata/commands/cache.py +7 -7
  23. udata/commands/db.py +201 -140
  24. udata/commands/dcat.py +36 -30
  25. udata/commands/fixtures.py +100 -84
  26. udata/commands/images.py +21 -20
  27. udata/commands/info.py +17 -20
  28. udata/commands/init.py +10 -10
  29. udata/commands/purge.py +12 -13
  30. udata/commands/serve.py +41 -29
  31. udata/commands/static.py +16 -18
  32. udata/commands/test.py +20 -20
  33. udata/commands/tests/fixtures.py +26 -24
  34. udata/commands/worker.py +31 -33
  35. udata/core/__init__.py +12 -12
  36. udata/core/activity/__init__.py +0 -1
  37. udata/core/activity/api.py +59 -49
  38. udata/core/activity/models.py +28 -26
  39. udata/core/activity/signals.py +1 -1
  40. udata/core/activity/tasks.py +16 -10
  41. udata/core/badges/api.py +6 -6
  42. udata/core/badges/commands.py +14 -13
  43. udata/core/badges/fields.py +8 -5
  44. udata/core/badges/forms.py +7 -4
  45. udata/core/badges/models.py +16 -31
  46. udata/core/badges/permissions.py +1 -3
  47. udata/core/badges/signals.py +2 -2
  48. udata/core/badges/tasks.py +3 -2
  49. udata/core/badges/tests/test_commands.py +10 -10
  50. udata/core/badges/tests/test_model.py +24 -31
  51. udata/core/contact_point/api.py +19 -18
  52. udata/core/contact_point/api_fields.py +21 -14
  53. udata/core/contact_point/factories.py +2 -2
  54. udata/core/contact_point/forms.py +7 -6
  55. udata/core/contact_point/models.py +3 -5
  56. udata/core/dataservices/api.py +26 -21
  57. udata/core/dataservices/factories.py +13 -11
  58. udata/core/dataservices/models.py +35 -40
  59. udata/core/dataservices/permissions.py +4 -4
  60. udata/core/dataservices/rdf.py +40 -17
  61. udata/core/dataservices/tasks.py +4 -3
  62. udata/core/dataset/actions.py +10 -10
  63. udata/core/dataset/activities.py +21 -23
  64. udata/core/dataset/api.py +321 -298
  65. udata/core/dataset/api_fields.py +443 -271
  66. udata/core/dataset/apiv2.py +305 -229
  67. udata/core/dataset/commands.py +38 -36
  68. udata/core/dataset/constants.py +61 -54
  69. udata/core/dataset/csv.py +70 -74
  70. udata/core/dataset/events.py +39 -32
  71. udata/core/dataset/exceptions.py +8 -4
  72. udata/core/dataset/factories.py +57 -65
  73. udata/core/dataset/forms.py +87 -63
  74. udata/core/dataset/models.py +336 -280
  75. udata/core/dataset/permissions.py +9 -6
  76. udata/core/dataset/preview.py +15 -17
  77. udata/core/dataset/rdf.py +156 -122
  78. udata/core/dataset/search.py +92 -77
  79. udata/core/dataset/signals.py +1 -1
  80. udata/core/dataset/tasks.py +63 -54
  81. udata/core/discussions/actions.py +5 -5
  82. udata/core/discussions/api.py +124 -120
  83. udata/core/discussions/factories.py +2 -2
  84. udata/core/discussions/forms.py +9 -7
  85. udata/core/discussions/metrics.py +1 -3
  86. udata/core/discussions/models.py +25 -24
  87. udata/core/discussions/notifications.py +18 -14
  88. udata/core/discussions/permissions.py +3 -3
  89. udata/core/discussions/signals.py +4 -4
  90. udata/core/discussions/tasks.py +24 -28
  91. udata/core/followers/api.py +32 -33
  92. udata/core/followers/models.py +9 -9
  93. udata/core/followers/signals.py +3 -3
  94. udata/core/jobs/actions.py +7 -7
  95. udata/core/jobs/api.py +99 -92
  96. udata/core/jobs/commands.py +48 -49
  97. udata/core/jobs/forms.py +11 -11
  98. udata/core/jobs/models.py +6 -6
  99. udata/core/metrics/__init__.py +2 -2
  100. udata/core/metrics/commands.py +34 -30
  101. udata/core/metrics/models.py +2 -4
  102. udata/core/metrics/signals.py +1 -1
  103. udata/core/metrics/tasks.py +3 -3
  104. udata/core/organization/activities.py +12 -15
  105. udata/core/organization/api.py +167 -174
  106. udata/core/organization/api_fields.py +183 -124
  107. udata/core/organization/apiv2.py +32 -32
  108. udata/core/organization/commands.py +20 -22
  109. udata/core/organization/constants.py +11 -11
  110. udata/core/organization/csv.py +17 -15
  111. udata/core/organization/factories.py +8 -11
  112. udata/core/organization/forms.py +32 -26
  113. udata/core/organization/metrics.py +2 -1
  114. udata/core/organization/models.py +87 -67
  115. udata/core/organization/notifications.py +18 -14
  116. udata/core/organization/permissions.py +10 -11
  117. udata/core/organization/rdf.py +14 -14
  118. udata/core/organization/search.py +30 -28
  119. udata/core/organization/signals.py +7 -7
  120. udata/core/organization/tasks.py +42 -61
  121. udata/core/owned.py +38 -27
  122. udata/core/post/api.py +82 -81
  123. udata/core/post/constants.py +8 -5
  124. udata/core/post/factories.py +4 -4
  125. udata/core/post/forms.py +13 -14
  126. udata/core/post/models.py +20 -22
  127. udata/core/post/tests/test_api.py +30 -32
  128. udata/core/reports/api.py +8 -7
  129. udata/core/reports/constants.py +1 -3
  130. udata/core/reports/models.py +10 -10
  131. udata/core/reuse/activities.py +15 -19
  132. udata/core/reuse/api.py +123 -126
  133. udata/core/reuse/api_fields.py +120 -85
  134. udata/core/reuse/apiv2.py +11 -10
  135. udata/core/reuse/constants.py +23 -23
  136. udata/core/reuse/csv.py +18 -18
  137. udata/core/reuse/factories.py +5 -9
  138. udata/core/reuse/forms.py +24 -21
  139. udata/core/reuse/models.py +55 -51
  140. udata/core/reuse/permissions.py +2 -2
  141. udata/core/reuse/search.py +49 -46
  142. udata/core/reuse/signals.py +1 -1
  143. udata/core/reuse/tasks.py +4 -5
  144. udata/core/site/api.py +47 -50
  145. udata/core/site/factories.py +2 -2
  146. udata/core/site/forms.py +4 -5
  147. udata/core/site/models.py +94 -63
  148. udata/core/site/rdf.py +14 -14
  149. udata/core/spam/api.py +16 -9
  150. udata/core/spam/constants.py +4 -4
  151. udata/core/spam/fields.py +13 -7
  152. udata/core/spam/models.py +27 -20
  153. udata/core/spam/signals.py +1 -1
  154. udata/core/spam/tests/test_spam.py +6 -5
  155. udata/core/spatial/api.py +72 -80
  156. udata/core/spatial/api_fields.py +73 -58
  157. udata/core/spatial/commands.py +67 -64
  158. udata/core/spatial/constants.py +3 -3
  159. udata/core/spatial/factories.py +37 -54
  160. udata/core/spatial/forms.py +27 -26
  161. udata/core/spatial/geoids.py +17 -17
  162. udata/core/spatial/models.py +43 -47
  163. udata/core/spatial/tasks.py +2 -1
  164. udata/core/spatial/tests/test_api.py +115 -130
  165. udata/core/spatial/tests/test_fields.py +74 -77
  166. udata/core/spatial/tests/test_geoid.py +22 -22
  167. udata/core/spatial/tests/test_models.py +5 -7
  168. udata/core/spatial/translations.py +16 -16
  169. udata/core/storages/__init__.py +16 -18
  170. udata/core/storages/api.py +66 -64
  171. udata/core/storages/tasks.py +7 -7
  172. udata/core/storages/utils.py +15 -15
  173. udata/core/storages/views.py +5 -6
  174. udata/core/tags/api.py +17 -14
  175. udata/core/tags/csv.py +4 -4
  176. udata/core/tags/models.py +8 -5
  177. udata/core/tags/tasks.py +11 -13
  178. udata/core/tags/views.py +4 -4
  179. udata/core/topic/api.py +84 -73
  180. udata/core/topic/apiv2.py +157 -127
  181. udata/core/topic/factories.py +3 -4
  182. udata/core/topic/forms.py +12 -14
  183. udata/core/topic/models.py +14 -19
  184. udata/core/topic/parsers.py +26 -26
  185. udata/core/user/activities.py +30 -29
  186. udata/core/user/api.py +151 -152
  187. udata/core/user/api_fields.py +132 -100
  188. udata/core/user/apiv2.py +7 -7
  189. udata/core/user/commands.py +38 -38
  190. udata/core/user/factories.py +8 -9
  191. udata/core/user/forms.py +14 -11
  192. udata/core/user/metrics.py +2 -2
  193. udata/core/user/models.py +68 -69
  194. udata/core/user/permissions.py +4 -5
  195. udata/core/user/rdf.py +7 -8
  196. udata/core/user/tasks.py +2 -2
  197. udata/core/user/tests/test_user_model.py +24 -16
  198. udata/db/tasks.py +2 -1
  199. udata/entrypoints.py +35 -31
  200. udata/errors.py +2 -1
  201. udata/event/values.py +6 -6
  202. udata/factories.py +2 -2
  203. udata/features/identicon/api.py +5 -6
  204. udata/features/identicon/backends.py +48 -55
  205. udata/features/identicon/tests/test_backends.py +4 -5
  206. udata/features/notifications/__init__.py +0 -1
  207. udata/features/notifications/actions.py +9 -9
  208. udata/features/notifications/api.py +17 -13
  209. udata/features/territories/__init__.py +12 -10
  210. udata/features/territories/api.py +14 -15
  211. udata/features/territories/models.py +23 -28
  212. udata/features/transfer/actions.py +8 -11
  213. udata/features/transfer/api.py +84 -77
  214. udata/features/transfer/factories.py +2 -1
  215. udata/features/transfer/models.py +11 -12
  216. udata/features/transfer/notifications.py +19 -15
  217. udata/features/transfer/permissions.py +5 -5
  218. udata/forms/__init__.py +5 -2
  219. udata/forms/fields.py +164 -172
  220. udata/forms/validators.py +19 -22
  221. udata/forms/widgets.py +9 -13
  222. udata/frontend/__init__.py +31 -26
  223. udata/frontend/csv.py +68 -58
  224. udata/frontend/markdown.py +40 -44
  225. udata/harvest/actions.py +89 -77
  226. udata/harvest/api.py +294 -238
  227. udata/harvest/backends/__init__.py +4 -4
  228. udata/harvest/backends/base.py +128 -111
  229. udata/harvest/backends/dcat.py +80 -66
  230. udata/harvest/commands.py +56 -60
  231. udata/harvest/csv.py +8 -8
  232. udata/harvest/exceptions.py +6 -3
  233. udata/harvest/filters.py +24 -23
  234. udata/harvest/forms.py +27 -28
  235. udata/harvest/models.py +88 -80
  236. udata/harvest/notifications.py +15 -10
  237. udata/harvest/signals.py +13 -13
  238. udata/harvest/tasks.py +11 -10
  239. udata/harvest/tests/factories.py +23 -24
  240. udata/harvest/tests/test_actions.py +136 -166
  241. udata/harvest/tests/test_api.py +220 -214
  242. udata/harvest/tests/test_base_backend.py +117 -112
  243. udata/harvest/tests/test_dcat_backend.py +380 -308
  244. udata/harvest/tests/test_filters.py +33 -22
  245. udata/harvest/tests/test_models.py +11 -14
  246. udata/harvest/tests/test_notifications.py +6 -7
  247. udata/harvest/tests/test_tasks.py +7 -6
  248. udata/i18n.py +237 -78
  249. udata/linkchecker/backends.py +5 -11
  250. udata/linkchecker/checker.py +23 -22
  251. udata/linkchecker/commands.py +4 -6
  252. udata/linkchecker/models.py +6 -6
  253. udata/linkchecker/tasks.py +18 -20
  254. udata/mail.py +21 -21
  255. udata/migrations/2020-07-24-remove-s-from-scope-oauth.py +9 -8
  256. udata/migrations/2020-08-24-add-fs-filename.py +9 -8
  257. udata/migrations/2020-09-28-update-reuses-datasets-metrics.py +5 -4
  258. udata/migrations/2020-10-16-migrate-ods-resources.py +9 -10
  259. udata/migrations/2021-04-08-update-schema-with-new-structure.py +8 -7
  260. udata/migrations/2021-05-27-fix-default-schema-name.py +7 -6
  261. udata/migrations/2021-07-05-remove-unused-badges.py +17 -15
  262. udata/migrations/2021-07-07-update-schema-for-community-resources.py +7 -6
  263. udata/migrations/2021-08-17-follow-integrity.py +5 -4
  264. udata/migrations/2021-08-17-harvest-integrity.py +13 -12
  265. udata/migrations/2021-08-17-oauth2client-integrity.py +5 -4
  266. udata/migrations/2021-08-17-transfer-integrity.py +5 -4
  267. udata/migrations/2021-08-17-users-integrity.py +9 -8
  268. udata/migrations/2021-12-14-reuse-topics.py +7 -6
  269. udata/migrations/2022-04-21-improve-extension-detection.py +8 -7
  270. udata/migrations/2022-09-22-clean-inactive-harvest-datasets.py +16 -14
  271. udata/migrations/2022-10-10-add-fs_uniquifier-to-user-model.py +6 -6
  272. udata/migrations/2022-10-10-migrate-harvest-extras.py +36 -26
  273. udata/migrations/2023-02-08-rename-internal-dates.py +46 -28
  274. udata/migrations/2024-01-29-fix-reuse-and-dataset-with-private-None.py +10 -8
  275. udata/migrations/2024-03-22-migrate-activity-kwargs-to-extras.py +6 -4
  276. udata/migrations/2024-06-11-fix-reuse-datasets-references.py +7 -6
  277. udata/migrations/__init__.py +123 -105
  278. udata/models/__init__.py +4 -4
  279. udata/mongo/__init__.py +13 -11
  280. udata/mongo/badges_field.py +3 -2
  281. udata/mongo/datetime_fields.py +13 -12
  282. udata/mongo/document.py +17 -16
  283. udata/mongo/engine.py +15 -16
  284. udata/mongo/errors.py +2 -1
  285. udata/mongo/extras_fields.py +30 -20
  286. udata/mongo/queryset.py +12 -12
  287. udata/mongo/slug_fields.py +38 -28
  288. udata/mongo/taglist_field.py +1 -2
  289. udata/mongo/url_field.py +5 -5
  290. udata/mongo/uuid_fields.py +4 -3
  291. udata/notifications/__init__.py +1 -1
  292. udata/notifications/mattermost.py +10 -9
  293. udata/rdf.py +167 -188
  294. udata/routing.py +40 -45
  295. udata/search/__init__.py +18 -19
  296. udata/search/adapter.py +17 -16
  297. udata/search/commands.py +44 -51
  298. udata/search/fields.py +13 -20
  299. udata/search/query.py +23 -18
  300. udata/search/result.py +9 -10
  301. udata/sentry.py +21 -19
  302. udata/settings.py +262 -198
  303. udata/sitemap.py +8 -6
  304. udata/static/chunks/{11.e9b9ca1f3e03d4020377.js → 11.52e531c19f8de80c00cf.js} +3 -3
  305. udata/static/chunks/{11.e9b9ca1f3e03d4020377.js.map → 11.52e531c19f8de80c00cf.js.map} +1 -1
  306. udata/static/chunks/{13.038c0d9aa0dfa0181c4b.js → 13.c3343a7f1070061c0e10.js} +2 -2
  307. udata/static/chunks/{13.038c0d9aa0dfa0181c4b.js.map → 13.c3343a7f1070061c0e10.js.map} +1 -1
  308. udata/static/chunks/{16.0baa2b64a74a2dcde25c.js → 16.8fa42440ad75ca172e6d.js} +2 -2
  309. udata/static/chunks/{16.0baa2b64a74a2dcde25c.js.map → 16.8fa42440ad75ca172e6d.js.map} +1 -1
  310. udata/static/chunks/{19.350a9f150b074b4ecefa.js → 19.9c6c8412729cd6d59cfa.js} +3 -3
  311. udata/static/chunks/{19.350a9f150b074b4ecefa.js.map → 19.9c6c8412729cd6d59cfa.js.map} +1 -1
  312. udata/static/chunks/{5.6ebbce2b9b3e696d3da5.js → 5.71d15c2e4f21feee2a9a.js} +3 -3
  313. udata/static/chunks/{5.6ebbce2b9b3e696d3da5.js.map → 5.71d15c2e4f21feee2a9a.js.map} +1 -1
  314. udata/static/chunks/{6.d8a5f7b017bcbd083641.js → 6.9139dc098b8ea640b890.js} +3 -3
  315. udata/static/chunks/{6.d8a5f7b017bcbd083641.js.map → 6.9139dc098b8ea640b890.js.map} +1 -1
  316. udata/static/common.js +1 -1
  317. udata/static/common.js.map +1 -1
  318. udata/storage/s3.py +20 -13
  319. udata/tags.py +4 -5
  320. udata/tasks.py +43 -42
  321. udata/tests/__init__.py +9 -6
  322. udata/tests/api/__init__.py +5 -6
  323. udata/tests/api/test_auth_api.py +395 -321
  324. udata/tests/api/test_base_api.py +31 -33
  325. udata/tests/api/test_contact_points.py +7 -9
  326. udata/tests/api/test_dataservices_api.py +211 -158
  327. udata/tests/api/test_datasets_api.py +823 -812
  328. udata/tests/api/test_follow_api.py +13 -15
  329. udata/tests/api/test_me_api.py +95 -112
  330. udata/tests/api/test_organizations_api.py +301 -339
  331. udata/tests/api/test_reports_api.py +35 -25
  332. udata/tests/api/test_reuses_api.py +134 -139
  333. udata/tests/api/test_swagger.py +5 -5
  334. udata/tests/api/test_tags_api.py +18 -25
  335. udata/tests/api/test_topics_api.py +94 -94
  336. udata/tests/api/test_transfer_api.py +53 -48
  337. udata/tests/api/test_user_api.py +128 -141
  338. udata/tests/apiv2/test_datasets.py +290 -198
  339. udata/tests/apiv2/test_me_api.py +10 -11
  340. udata/tests/apiv2/test_organizations.py +56 -74
  341. udata/tests/apiv2/test_swagger.py +5 -5
  342. udata/tests/apiv2/test_topics.py +69 -87
  343. udata/tests/cli/test_cli_base.py +8 -8
  344. udata/tests/cli/test_db_cli.py +21 -19
  345. udata/tests/dataservice/test_dataservice_tasks.py +8 -12
  346. udata/tests/dataset/test_csv_adapter.py +44 -35
  347. udata/tests/dataset/test_dataset_actions.py +2 -3
  348. udata/tests/dataset/test_dataset_commands.py +7 -8
  349. udata/tests/dataset/test_dataset_events.py +36 -29
  350. udata/tests/dataset/test_dataset_model.py +224 -217
  351. udata/tests/dataset/test_dataset_rdf.py +142 -131
  352. udata/tests/dataset/test_dataset_tasks.py +15 -15
  353. udata/tests/dataset/test_resource_preview.py +10 -13
  354. udata/tests/features/territories/__init__.py +9 -13
  355. udata/tests/features/territories/test_territories_api.py +71 -91
  356. udata/tests/forms/test_basic_fields.py +7 -7
  357. udata/tests/forms/test_current_user_field.py +39 -66
  358. udata/tests/forms/test_daterange_field.py +31 -39
  359. udata/tests/forms/test_dict_field.py +28 -26
  360. udata/tests/forms/test_extras_fields.py +102 -76
  361. udata/tests/forms/test_form_field.py +8 -8
  362. udata/tests/forms/test_image_field.py +33 -26
  363. udata/tests/forms/test_model_field.py +134 -123
  364. udata/tests/forms/test_model_list_field.py +7 -7
  365. udata/tests/forms/test_nested_model_list_field.py +117 -79
  366. udata/tests/forms/test_publish_as_field.py +36 -65
  367. udata/tests/forms/test_reference_field.py +34 -53
  368. udata/tests/forms/test_user_forms.py +23 -21
  369. udata/tests/forms/test_uuid_field.py +6 -10
  370. udata/tests/frontend/__init__.py +9 -6
  371. udata/tests/frontend/test_auth.py +7 -6
  372. udata/tests/frontend/test_csv.py +81 -96
  373. udata/tests/frontend/test_hooks.py +43 -43
  374. udata/tests/frontend/test_markdown.py +211 -191
  375. udata/tests/helpers.py +32 -37
  376. udata/tests/models.py +2 -2
  377. udata/tests/organization/test_csv_adapter.py +21 -16
  378. udata/tests/organization/test_notifications.py +11 -18
  379. udata/tests/organization/test_organization_model.py +13 -13
  380. udata/tests/organization/test_organization_rdf.py +29 -22
  381. udata/tests/organization/test_organization_tasks.py +16 -17
  382. udata/tests/plugin.py +76 -73
  383. udata/tests/reuse/test_reuse_model.py +21 -21
  384. udata/tests/reuse/test_reuse_task.py +11 -13
  385. udata/tests/search/__init__.py +11 -12
  386. udata/tests/search/test_adapter.py +60 -70
  387. udata/tests/search/test_query.py +16 -16
  388. udata/tests/search/test_results.py +10 -7
  389. udata/tests/site/test_site_api.py +11 -16
  390. udata/tests/site/test_site_metrics.py +20 -30
  391. udata/tests/site/test_site_model.py +4 -5
  392. udata/tests/site/test_site_rdf.py +94 -78
  393. udata/tests/test_activity.py +17 -17
  394. udata/tests/test_discussions.py +292 -299
  395. udata/tests/test_i18n.py +37 -40
  396. udata/tests/test_linkchecker.py +91 -85
  397. udata/tests/test_mail.py +13 -17
  398. udata/tests/test_migrations.py +219 -180
  399. udata/tests/test_model.py +164 -157
  400. udata/tests/test_notifications.py +17 -17
  401. udata/tests/test_owned.py +14 -14
  402. udata/tests/test_rdf.py +25 -23
  403. udata/tests/test_routing.py +89 -93
  404. udata/tests/test_storages.py +137 -128
  405. udata/tests/test_tags.py +44 -46
  406. udata/tests/test_topics.py +7 -7
  407. udata/tests/test_transfer.py +42 -49
  408. udata/tests/test_uris.py +160 -161
  409. udata/tests/test_utils.py +79 -71
  410. udata/tests/user/test_user_rdf.py +5 -9
  411. udata/tests/workers/test_jobs_commands.py +57 -58
  412. udata/tests/workers/test_tasks_routing.py +23 -29
  413. udata/tests/workers/test_workers_api.py +125 -131
  414. udata/tests/workers/test_workers_helpers.py +6 -6
  415. udata/tracking.py +4 -6
  416. udata/uris.py +45 -46
  417. udata/utils.py +68 -66
  418. udata/wsgi.py +1 -1
  419. {udata-9.1.2.dev30355.dist-info → udata-9.1.2.dev30382.dist-info}/METADATA +3 -2
  420. udata-9.1.2.dev30382.dist-info/RECORD +704 -0
  421. udata-9.1.2.dev30355.dist-info/RECORD +0 -704
  422. {udata-9.1.2.dev30355.dist-info → udata-9.1.2.dev30382.dist-info}/LICENSE +0 -0
  423. {udata-9.1.2.dev30355.dist-info → udata-9.1.2.dev30382.dist-info}/WHEEL +0 -0
  424. {udata-9.1.2.dev30355.dist-info → udata-9.1.2.dev30382.dist-info}/entry_points.txt +0 -0
  425. {udata-9.1.2.dev30355.dist-info → udata-9.1.2.dev30382.dist-info}/top_level.txt +0 -0
@@ -51,7 +51,7 @@ class FormFieldTest(TestCase):
51
51
 
52
52
  def test_with_one_valid_data(self):
53
53
  fake = Fake()
54
- form = self.factory(MultiDict({'nested-name': 'John Doe'}))
54
+ form = self.factory(MultiDict({"nested-name": "John Doe"}))
55
55
 
56
56
  form.validate()
57
57
  self.assertEqual(form.errors, {})
@@ -59,11 +59,11 @@ class FormFieldTest(TestCase):
59
59
  form.populate_obj(fake)
60
60
 
61
61
  self.assertIsInstance(fake.nested, Nested)
62
- self.assertEqual(fake.nested.name, 'John Doe')
62
+ self.assertEqual(fake.nested.name, "John Doe")
63
63
 
64
64
  def test_with_one_valid_json(self):
65
65
  fake = Fake()
66
- form = self.factory({'nested': {'name': 'John Doe'}})
66
+ form = self.factory({"nested": {"name": "John Doe"}})
67
67
 
68
68
  form.validate()
69
69
  self.assertEqual(form.errors, {})
@@ -71,12 +71,12 @@ class FormFieldTest(TestCase):
71
71
  form.populate_obj(fake)
72
72
 
73
73
  self.assertIsInstance(fake.nested, Nested)
74
- self.assertEqual(fake.nested.name, 'John Doe')
74
+ self.assertEqual(fake.nested.name, "John Doe")
75
75
 
76
76
  def test_with_initial_elements(self):
77
77
  fake = Fake.objects.create(nested=Nested(name=faker.name()))
78
78
  new_name = faker.name()
79
- form = self.factory({'nested': {'name': new_name}}, fake)
79
+ form = self.factory({"nested": {"name": new_name}}, fake)
80
80
 
81
81
  form.validate()
82
82
  self.assertEqual(form.errors, {})
@@ -90,7 +90,7 @@ class FormFieldTest(TestCase):
90
90
  fake = Fake.objects.create(nested=Nested(name=faker.name()))
91
91
  initial_id = fake.nested.id
92
92
  initial_name = fake.nested.name
93
- form = self.factory({'name': faker.word()}, fake)
93
+ form = self.factory({"name": faker.word()}, fake)
94
94
 
95
95
  form.validate()
96
96
  self.assertEqual(form.errors, {})
@@ -104,7 +104,7 @@ class FormFieldTest(TestCase):
104
104
  fake = Fake.objects.create(nested=Nested(name=faker.name()))
105
105
  initial_id = fake.nested.id
106
106
  new_name = faker.name()
107
- form = self.factory({'nested': {'name': new_name}}, fake)
107
+ form = self.factory({"nested": {"name": new_name}}, fake)
108
108
 
109
109
  form.validate()
110
110
  self.assertEqual(form.errors, {})
@@ -115,7 +115,7 @@ class FormFieldTest(TestCase):
115
115
  self.assertEqual(fake.nested.name, new_name)
116
116
 
117
117
  def test_create_with_non_submitted_elements(self):
118
- form = self.factory({'name': faker.word()})
118
+ form = self.factory({"name": faker.word()})
119
119
 
120
120
  form.validate()
121
121
  self.assertEqual(form.errors, {})
@@ -1,20 +1,19 @@
1
1
  import logging
2
2
 
3
- import pytest
4
-
5
3
  import flask_storage as fs
4
+ import pytest
6
5
 
7
- from udata.mongo import db
6
+ from udata.core.storages import tmp
8
7
  from udata.forms import Form
9
8
  from udata.forms.fields import ImageField
9
+ from udata.mongo import db
10
10
  from udata.tests.helpers import data_path
11
- from udata.core.storages import tmp
12
11
 
13
12
  log = logging.getLogger(__name__)
14
13
 
15
14
  SIZES = [16, 32]
16
15
 
17
- storage = fs.Storage('test')
16
+ storage = fs.Storage("test")
18
17
 
19
18
 
20
19
  class PostData(dict):
@@ -25,7 +24,7 @@ class PostData(dict):
25
24
  return value
26
25
 
27
26
 
28
- @pytest.mark.usefixtures('clean_db')
27
+ @pytest.mark.usefixtures("clean_db")
29
28
  class ImageFieldTest:
30
29
  class D(db.Document):
31
30
  image = db.ImageField(fs=storage)
@@ -37,7 +36,7 @@ class ImageFieldTest:
37
36
 
38
37
  @pytest.fixture(autouse=True)
39
38
  def fs_root(self, instance_path, app):
40
- app.config['FS_ROOT'] = str(instance_path / 'fs')
39
+ app.config["FS_ROOT"] = str(instance_path / "fs")
41
40
  fs.init_app(app, storage, tmp)
42
41
 
43
42
  def test_empty(self):
@@ -59,30 +58,34 @@ class ImageFieldTest:
59
58
 
60
59
  def test_with_image(self):
61
60
  doc = self.D()
62
- with open(data_path('image.png'), 'rb') as img:
63
- doc.image.save(img, 'image.jpg')
61
+ with open(data_path("image.png"), "rb") as img:
62
+ doc.image.save(img, "image.jpg")
64
63
  doc.save()
65
64
  form = self.F(None, obj=doc)
66
- assert form.image.filename.data == 'image.jpg'
65
+ assert form.image.filename.data == "image.jpg"
67
66
  assert form.image.bbox.data is None
68
67
 
69
68
  def test_with_image_and_bbox(self):
70
69
  doc = self.D()
71
- with open(data_path('image.png'), 'rb') as img:
72
- doc.thumbnail.save(img, 'image.jpg', bbox=[10, 10, 100, 100])
70
+ with open(data_path("image.png"), "rb") as img:
71
+ doc.thumbnail.save(img, "image.jpg", bbox=[10, 10, 100, 100])
73
72
  doc.save()
74
73
  form = self.F(None, obj=doc)
75
- assert form.thumbnail.filename.data == 'image.jpg'
74
+ assert form.thumbnail.filename.data == "image.jpg"
76
75
  assert form.thumbnail.bbox.data == [10, 10, 100, 100]
77
76
 
78
77
  def test_post_new(self):
79
- tmp_filename = 'xyz/image.png'
80
- with open(data_path('image.png'), 'rb') as img:
78
+ tmp_filename = "xyz/image.png"
79
+ with open(data_path("image.png"), "rb") as img:
81
80
  tmp_filename = tmp.save(img, tmp_filename)
82
81
 
83
- form = self.F(PostData({
84
- 'image-filename': tmp_filename,
85
- }))
82
+ form = self.F(
83
+ PostData(
84
+ {
85
+ "image-filename": tmp_filename,
86
+ }
87
+ )
88
+ )
86
89
 
87
90
  assert form.image.filename.data == tmp_filename
88
91
  assert form.image.bbox.data is None
@@ -91,19 +94,23 @@ class ImageFieldTest:
91
94
  form.populate_obj(doc)
92
95
 
93
96
  assert doc.image.bbox is None
94
- assert doc.image.filename.endswith('.png')
97
+ assert doc.image.filename.endswith(".png")
95
98
  assert doc.image.filename in storage
96
99
  assert tmp_filename not in tmp
97
100
 
98
101
  def test_post_new_with_crop(self):
99
- tmp_filename = 'xyz/image.png'
100
- with open(data_path('image.png'), 'rb') as img:
102
+ tmp_filename = "xyz/image.png"
103
+ with open(data_path("image.png"), "rb") as img:
101
104
  tmp_filename = tmp.save(img, tmp_filename)
102
105
 
103
- form = self.F(PostData({
104
- 'thumbnail-filename': tmp_filename,
105
- 'thumbnail-bbox': '10,10,100,100',
106
- }))
106
+ form = self.F(
107
+ PostData(
108
+ {
109
+ "thumbnail-filename": tmp_filename,
110
+ "thumbnail-bbox": "10,10,100,100",
111
+ }
112
+ )
113
+ )
107
114
 
108
115
  assert form.thumbnail.filename.data == tmp_filename
109
116
  assert form.thumbnail.bbox.data == [10, 10, 100, 100]
@@ -112,6 +119,6 @@ class ImageFieldTest:
112
119
  form.populate_obj(doc)
113
120
 
114
121
  assert doc.thumbnail.bbox == [10, 10, 100, 100]
115
- assert doc.thumbnail.filename.endswith('.png')
122
+ assert doc.thumbnail.filename.endswith(".png")
116
123
  assert doc.thumbnail.filename in storage
117
124
  assert tmp_filename not in tmp
@@ -1,15 +1,11 @@
1
1
  import pytest
2
-
3
2
  from werkzeug.datastructures import MultiDict
4
3
 
5
4
  from udata.forms import ModelForm, fields
6
5
  from udata.i18n import gettext as _
7
6
  from udata.mongo import db
8
7
 
9
-
10
- pytestmark = [
11
- pytest.mark.usefixtures('clean_db')
12
- ]
8
+ pytestmark = [pytest.mark.usefixtures("clean_db")]
13
9
 
14
10
 
15
11
  class Target(db.Document):
@@ -31,44 +27,47 @@ class Generic:
31
27
 
32
28
  def test_error_with_inline_identifier(self):
33
29
  expected_target = Target.objects.create()
34
- form = self.form.from_json({
35
- 'name': 'test',
36
- 'target': str(expected_target.pk),
37
- })
30
+ form = self.form.from_json(
31
+ {
32
+ "name": "test",
33
+ "target": str(expected_target.pk),
34
+ }
35
+ )
38
36
 
39
37
  form.validate()
40
38
 
41
- assert 'target' in form.errors
42
- assert len(form.errors['target']) == 1
43
- assert form.errors['target'][0] == _('Expect both class and identifier')
39
+ assert "target" in form.errors
40
+ assert len(form.errors["target"]) == 1
41
+ assert form.errors["target"][0] == _("Expect both class and identifier")
44
42
 
45
43
  def test_error_with_identifier_only(self):
46
44
  expected_target = Target.objects.create()
47
- form = self.form.from_json({
48
- 'name': 'test',
49
- 'target': {'id': str(expected_target.pk)},
50
- })
45
+ form = self.form.from_json(
46
+ {
47
+ "name": "test",
48
+ "target": {"id": str(expected_target.pk)},
49
+ }
50
+ )
51
51
 
52
52
  form.validate()
53
53
 
54
- assert 'target' in form.errors
55
- assert len(form.errors['target']) == 1
56
- assert form.errors['target'][0] == _('Expect both class and identifier')
54
+ assert "target" in form.errors
55
+ assert len(form.errors["target"]) == 1
56
+ assert form.errors["target"][0] == _("Expect both class and identifier")
57
57
 
58
58
  def test_error_with_unknown_model(self):
59
- form = self.form.from_json({
60
- 'name': 'test',
61
- 'target': {
62
- 'class': 'Unknown',
63
- 'id': 42
64
- },
65
- })
59
+ form = self.form.from_json(
60
+ {
61
+ "name": "test",
62
+ "target": {"class": "Unknown", "id": 42},
63
+ }
64
+ )
66
65
 
67
66
  form.validate()
68
67
 
69
- assert 'target' in form.errors
70
- assert len(form.errors['target']) == 1
71
- assert form.errors['target'][0] == 'Model "Unknown" does not exist'
68
+ assert "target" in form.errors
69
+ assert len(form.errors["target"]) == 1
70
+ assert form.errors["target"][0] == 'Model "Unknown" does not exist'
72
71
 
73
72
 
74
73
  class Explicit:
@@ -77,10 +76,14 @@ class Explicit:
77
76
  def test_with_inline_identifier_multidict(self):
78
77
  expected_target = Target.objects.create()
79
78
  model = self.model()
80
- form = self.form(MultiDict({
81
- 'name': 'test',
82
- 'target': str(expected_target.pk),
83
- }))
79
+ form = self.form(
80
+ MultiDict(
81
+ {
82
+ "name": "test",
83
+ "target": str(expected_target.pk),
84
+ }
85
+ )
86
+ )
84
87
 
85
88
  form.validate()
86
89
  assert form.errors == {}
@@ -93,10 +96,14 @@ class Explicit:
93
96
  def test_with_identifier_only_multidict(self):
94
97
  expected_target = Target.objects.create()
95
98
  model = self.model()
96
- form = self.form(MultiDict({
97
- 'name': 'test',
98
- 'target-id': str(expected_target.pk),
99
- }))
99
+ form = self.form(
100
+ MultiDict(
101
+ {
102
+ "name": "test",
103
+ "target-id": str(expected_target.pk),
104
+ }
105
+ )
106
+ )
100
107
 
101
108
  form.validate()
102
109
  assert form.errors == {}
@@ -109,10 +116,12 @@ class Explicit:
109
116
  def test_with_inline_identifier_json(self):
110
117
  expected_target = Target.objects.create()
111
118
  model = self.model()
112
- form = self.form.from_json({
113
- 'name': 'test',
114
- 'target': str(expected_target.pk),
115
- })
119
+ form = self.form.from_json(
120
+ {
121
+ "name": "test",
122
+ "target": str(expected_target.pk),
123
+ }
124
+ )
116
125
 
117
126
  form.validate()
118
127
  assert form.errors == {}
@@ -125,10 +134,12 @@ class Explicit:
125
134
  def test_with_identifier_only_json(self):
126
135
  expected_target = Target.objects.create()
127
136
  model = self.model()
128
- form = self.form.from_json({
129
- 'name': 'test',
130
- 'target': {'id': str(expected_target.pk)},
131
- })
137
+ form = self.form.from_json(
138
+ {
139
+ "name": "test",
140
+ "target": {"id": str(expected_target.pk)},
141
+ }
142
+ )
132
143
 
133
144
  form.validate()
134
145
  assert form.errors == {}
@@ -140,71 +151,79 @@ class Explicit:
140
151
 
141
152
  def test_error_with_class_mismatch(self):
142
153
  expected_target = Target.objects.create()
143
- form = self.form.from_json({
144
- 'name': 'test',
145
- 'target': {
146
- 'class': 'Wrong',
147
- 'id': str(expected_target.pk)
148
- },
149
- })
154
+ form = self.form.from_json(
155
+ {
156
+ "name": "test",
157
+ "target": {"class": "Wrong", "id": str(expected_target.pk)},
158
+ }
159
+ )
150
160
 
151
161
  form.validate()
152
162
 
153
- assert 'target' in form.errors
154
- assert len(form.errors['target']) == 1
155
- assert form.errors['target'][0] == _('Expect a "Target" class but "Wrong" was found')
163
+ assert "target" in form.errors
164
+ assert len(form.errors["target"]) == 1
165
+ assert form.errors["target"][0] == _('Expect a "Target" class but "Wrong" was found')
156
166
 
157
167
 
158
168
  class Required:
159
169
  required = True
160
170
 
161
171
  def test_not_provided(self):
162
- form = self.form.from_json({'name': 'test'})
172
+ form = self.form.from_json({"name": "test"})
163
173
 
164
174
  form.validate()
165
175
 
166
- assert 'target' in form.errors
167
- assert len(form.errors['target']) == 1
168
- assert 'requis' in form.errors['target'][0]
176
+ assert "target" in form.errors
177
+ assert len(form.errors["target"]) == 1
178
+ assert "requis" in form.errors["target"][0]
169
179
 
170
180
  def test_none(self):
171
- form = self.form.from_json({
172
- 'name': 'test',
173
- 'target': None,
174
- })
181
+ form = self.form.from_json(
182
+ {
183
+ "name": "test",
184
+ "target": None,
185
+ }
186
+ )
175
187
 
176
188
  form.validate()
177
189
 
178
- assert 'target' in form.errors
179
- assert len(form.errors['target']) == 1
180
- assert 'requis' in form.errors['target'][0]
190
+ assert "target" in form.errors
191
+ assert len(form.errors["target"]) == 1
192
+ assert "requis" in form.errors["target"][0]
181
193
 
182
194
  def test_with_initial_object_none(self):
183
195
  model = self.model(target=Target.objects.create())
184
196
 
185
- form = self.form.from_json({
186
- 'name': 'test',
187
- 'target': None,
188
- }, model)
197
+ form = self.form.from_json(
198
+ {
199
+ "name": "test",
200
+ "target": None,
201
+ },
202
+ model,
203
+ )
189
204
 
190
205
  form.validate()
191
206
 
192
- assert 'target' in form.errors
193
- assert len(form.errors['target']) == 1
194
- assert 'requis' in form.errors['target'][0]
207
+ assert "target" in form.errors
208
+ assert len(form.errors["target"]) == 1
209
+ assert "requis" in form.errors["target"][0]
195
210
 
196
211
 
197
212
  class Optionnal:
198
- '''Optional ModelField specific tests'''
213
+ """Optional ModelField specific tests"""
214
+
199
215
  required = False
200
216
 
201
217
  def test_with_initial_object_none(self):
202
218
  model = self.model(target=Target.objects.create())
203
219
 
204
- form = self.form.from_json({
205
- 'name': 'test',
206
- 'target': None,
207
- }, model)
220
+ form = self.form.from_json(
221
+ {
222
+ "name": "test",
223
+ "target": None,
224
+ },
225
+ model,
226
+ )
208
227
 
209
228
  form.validate()
210
229
  assert form.errors == {}
@@ -236,11 +255,11 @@ class CommonMixin:
236
255
  def test_with_valid_multidict(self):
237
256
  expected_target = Target.objects.create()
238
257
  model = self.model()
239
- form = self.form(MultiDict({
240
- 'name': 'test',
241
- 'target-class': 'Target',
242
- 'target-id': str(expected_target.pk)
243
- }))
258
+ form = self.form(
259
+ MultiDict(
260
+ {"name": "test", "target-class": "Target", "target-id": str(expected_target.pk)}
261
+ )
262
+ )
244
263
 
245
264
  form.validate()
246
265
  assert form.errors == {}
@@ -253,13 +272,9 @@ class CommonMixin:
253
272
  def test_with_valid_json(self):
254
273
  expected_target = Target.objects.create()
255
274
  model = self.model()
256
- form = self.form.from_json({
257
- 'name': 'test',
258
- 'target': {
259
- 'class': 'Target',
260
- 'id': str(expected_target.pk)
261
- }
262
- })
275
+ form = self.form.from_json(
276
+ {"name": "test", "target": {"class": "Target", "id": str(expected_target.pk)}}
277
+ )
263
278
 
264
279
  form.validate()
265
280
  assert form.errors == {}
@@ -274,13 +289,9 @@ class CommonMixin:
274
289
  expected_target = Target.objects.create()
275
290
  model = self.model(target=initial_target)
276
291
 
277
- form = self.form.from_json({
278
- 'name': 'test',
279
- 'target': {
280
- 'class': 'Target',
281
- 'id': str(expected_target.pk)
282
- }
283
- }, model)
292
+ form = self.form.from_json(
293
+ {"name": "test", "target": {"class": "Target", "id": str(expected_target.pk)}}, model
294
+ )
284
295
 
285
296
  form.validate()
286
297
  assert form.errors == {}
@@ -294,7 +305,7 @@ class CommonMixin:
294
305
  expected_target = Target.objects.create()
295
306
  model = self.model(target=expected_target)
296
307
 
297
- form = self.form.from_json({'name': 'test'}, model)
308
+ form = self.form.from_json({"name": "test"}, model)
298
309
 
299
310
  form.validate()
300
311
  assert form.errors == {}
@@ -305,46 +316,46 @@ class CommonMixin:
305
316
  assert model.target == expected_target
306
317
 
307
318
  def test_multidict_errors(self):
308
- form = self.form(MultiDict({
309
- 'name': 'test',
310
- 'target-class': 'Target',
311
- }))
319
+ form = self.form(
320
+ MultiDict(
321
+ {
322
+ "name": "test",
323
+ "target-class": "Target",
324
+ }
325
+ )
326
+ )
312
327
 
313
328
  form.validate()
314
329
 
315
- assert 'target' in form.errors
316
- assert len(form.errors['target']) == 1
330
+ assert "target" in form.errors
331
+ assert len(form.errors["target"]) == 1
317
332
  # assert 'Unsupported identifier' in form.errors['target'][0]
318
- assert form.errors['target'][0] == _('Missing "id" field')
333
+ assert form.errors["target"][0] == _('Missing "id" field')
319
334
 
320
335
  def test_json_errors(self):
321
- form = self.form.from_json({
322
- 'name': 'test',
323
- 'target': {
324
- 'class': 'Target',
336
+ form = self.form.from_json(
337
+ {
338
+ "name": "test",
339
+ "target": {
340
+ "class": "Target",
341
+ },
325
342
  }
326
- })
343
+ )
327
344
 
328
345
  form.validate()
329
346
 
330
- assert 'target' in form.errors
331
- assert len(form.errors['target']) == 1
332
- assert form.errors['target'][0] == _('Missing "id" field')
347
+ assert "target" in form.errors
348
+ assert len(form.errors["target"]) == 1
349
+ assert form.errors["target"][0] == _('Missing "id" field')
333
350
 
334
351
  def test_bad_id(self):
335
- form = self.form.from_json({
336
- 'name': 'test',
337
- 'target': {
338
- 'class': 'Target',
339
- 'id': 'wrong'
340
- }
341
- })
352
+ form = self.form.from_json({"name": "test", "target": {"class": "Target", "id": "wrong"}})
342
353
 
343
354
  form.validate()
344
355
 
345
- assert 'target' in form.errors
346
- assert len(form.errors['target']) == 1
347
- assert 'Unsupported identifier' in form.errors['target'][0]
356
+ assert "target" in form.errors
357
+ assert len(form.errors["target"]) == 1
358
+ assert "Unsupported identifier" in form.errors["target"][0]
348
359
 
349
360
 
350
361
  class Optionnal_GenericReference_Test(Generic, Optionnal, CommonMixin):
@@ -36,7 +36,7 @@ class ModelListFieldTest(TestCase):
36
36
  def test_with_one_valid_data(self):
37
37
  nested = Nested.objects.create(name=faker.name())
38
38
  fake = Fake()
39
- form = FakeForm(MultiDict({'nested': str(nested.id)}))
39
+ form = FakeForm(MultiDict({"nested": str(nested.id)}))
40
40
 
41
41
  form.validate()
42
42
  self.assertEqual(form.errors, {})
@@ -51,7 +51,7 @@ class ModelListFieldTest(TestCase):
51
51
  nesteds = [Nested.objects.create(name=faker.name()) for _ in range(3)]
52
52
  ids = [str(n.id) for n in nesteds]
53
53
  fake = Fake()
54
- form = FakeForm(MultiDict({'nested': ','.join(ids)}))
54
+ form = FakeForm(MultiDict({"nested": ",".join(ids)}))
55
55
 
56
56
  form.validate()
57
57
  self.assertEqual(form.errors, {})
@@ -65,7 +65,7 @@ class ModelListFieldTest(TestCase):
65
65
  def test_with_one_valid_json_id(self):
66
66
  nested = Nested.objects.create(name=faker.name())
67
67
  fake = Fake()
68
- form = FakeForm.from_json({'nested': [str(nested.id)]})
68
+ form = FakeForm.from_json({"nested": [str(nested.id)]})
69
69
 
70
70
  form.validate()
71
71
  self.assertEqual(form.errors, {})
@@ -79,7 +79,7 @@ class ModelListFieldTest(TestCase):
79
79
  def test_with_one_valid_json_object(self):
80
80
  nested = Nested.objects.create(name=faker.name())
81
81
  fake = Fake()
82
- form = FakeForm.from_json({'nested': [{'id': str(nested.id)}]})
82
+ form = FakeForm.from_json({"nested": [{"id": str(nested.id)}]})
83
83
 
84
84
  form.validate()
85
85
  self.assertEqual(form.errors, {})
@@ -94,7 +94,7 @@ class ModelListFieldTest(TestCase):
94
94
  nested = [Nested.objects.create(name=faker.name()) for _ in range(3)]
95
95
  ids = [str(n.id) for n in nested]
96
96
  fake = Fake()
97
- form = FakeForm.from_json({'nested': ids})
97
+ form = FakeForm.from_json({"nested": ids})
98
98
 
99
99
  form.validate()
100
100
  self.assertEqual(form.errors, {})
@@ -107,9 +107,9 @@ class ModelListFieldTest(TestCase):
107
107
 
108
108
  def test_with_multiple_valid_json_object(self):
109
109
  nested = [Nested.objects.create(name=faker.name()) for _ in range(3)]
110
- ids = [{'id': str(n.id)} for n in nested]
110
+ ids = [{"id": str(n.id)} for n in nested]
111
111
  fake = Fake()
112
- form = FakeForm.from_json({'nested': ids})
112
+ form = FakeForm.from_json({"nested": ids})
113
113
 
114
114
  form.validate()
115
115
  self.assertEqual(form.errors, {})