wbcore 1.46.0__py2.py3-none-any.whl → 1.58.2__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.
Files changed (321) hide show
  1. wbcore/cache/decorators.py +5 -3
  2. wbcore/cache/registry.py +14 -7
  3. wbcore/configs/__init__.py +1 -0
  4. wbcore/configs/configs.py +5 -0
  5. wbcore/configs/decorators.py +1 -1
  6. wbcore/configurations/configurations/apps.py +3 -2
  7. wbcore/configurations/configurations/authentication.py +1 -1
  8. wbcore/configurations/configurations/base.py +1 -1
  9. wbcore/configurations/configurations/cache.py +1 -1
  10. wbcore/configurations/configurations/i18nl10n.py +2 -1
  11. wbcore/configurations/configurations/maintenance.py +1 -1
  12. wbcore/configurations/configurations/media.py +1 -1
  13. wbcore/configurations/configurations/middleware.py +1 -1
  14. wbcore/configurations/configurations/rest_framework.py +1 -1
  15. wbcore/configurations/configurations/static.py +3 -3
  16. wbcore/configurations/configurations/wbcore.py +1 -1
  17. wbcore/content_type/serializers.py +13 -5
  18. wbcore/content_type/utils.py +3 -3
  19. wbcore/content_type/viewsets.py +2 -2
  20. wbcore/contrib/agenda/filters/calendar_item.py +5 -4
  21. wbcore/contrib/agenda/locale/de/LC_MESSAGES/django.po +145 -52
  22. wbcore/contrib/agenda/locale/de/LC_MESSAGES/django.po.translated +236 -0
  23. wbcore/contrib/agenda/locale/en/LC_MESSAGES/django.po +200 -0
  24. wbcore/contrib/agenda/locale/fr/LC_MESSAGES/django.po +201 -0
  25. wbcore/contrib/agenda/viewsets/calendar_items.py +7 -7
  26. wbcore/contrib/agenda/viewsets/menu/calendar_items.py +0 -6
  27. wbcore/contrib/ai/exceptions.py +5 -5
  28. wbcore/contrib/ai/llm/config.py +76 -27
  29. wbcore/contrib/ai/llm/mixins.py +5 -8
  30. wbcore/contrib/ai/llm/utils.py +50 -26
  31. wbcore/contrib/authentication/admin.py +2 -2
  32. wbcore/contrib/authentication/factories/__init__.py +8 -1
  33. wbcore/contrib/authentication/factories/users.py +19 -0
  34. wbcore/contrib/authentication/filters.py +1 -2
  35. wbcore/contrib/authentication/locale/de/LC_MESSAGES/django.po +209 -187
  36. wbcore/contrib/authentication/locale/de/LC_MESSAGES/django.po.translated +634 -0
  37. wbcore/contrib/authentication/locale/en/LC_MESSAGES/django.po +590 -0
  38. wbcore/contrib/authentication/locale/fr/LC_MESSAGES/django.po +592 -0
  39. wbcore/contrib/authentication/models/users.py +3 -3
  40. wbcore/contrib/authentication/models/users_activities.py +1 -1
  41. wbcore/contrib/authentication/serializers/users.py +2 -2
  42. wbcore/contrib/authentication/tests/test_tokens.py +3 -3
  43. wbcore/contrib/authentication/tests/test_users.py +0 -1
  44. wbcore/contrib/authentication/urls.py +0 -4
  45. wbcore/contrib/authentication/viewsets/endpoints/user_activities.py +2 -11
  46. wbcore/contrib/authentication/viewsets/endpoints/users.py +0 -3
  47. wbcore/contrib/authentication/viewsets/user_activities.py +2 -1
  48. wbcore/contrib/authentication/viewsets/users.py +6 -4
  49. wbcore/contrib/color/models.py +2 -1
  50. wbcore/contrib/currency/factories.py +1 -1
  51. wbcore/contrib/currency/import_export/backends/fixerio/currency_fx_rates.py +3 -1
  52. wbcore/contrib/currency/models.py +30 -8
  53. wbcore/contrib/currency/serializers.py +5 -1
  54. wbcore/contrib/currency/tests/test_serializers.py +7 -3
  55. wbcore/contrib/currency/tests/test_viewsets.py +1 -1
  56. wbcore/contrib/currency/viewsets/currency.py +2 -2
  57. wbcore/contrib/currency/viewsets/endpoints/currency_fx_rates.py +0 -9
  58. wbcore/contrib/dataloader/tests/test/dataloaders/protocols.py +1 -2
  59. wbcore/contrib/dataloader/utils.py +2 -2
  60. wbcore/contrib/directory/factories/__init__.py +1 -1
  61. wbcore/contrib/directory/factories/entries.py +2 -1
  62. wbcore/contrib/directory/filters/entries.py +9 -0
  63. wbcore/contrib/directory/locale/de/LC_MESSAGES/django.po +728 -714
  64. wbcore/contrib/directory/locale/de/LC_MESSAGES/django.po.translated +1779 -0
  65. wbcore/contrib/directory/locale/en/LC_MESSAGES/django.po +1652 -0
  66. wbcore/contrib/directory/locale/fr/LC_MESSAGES/django.po +1654 -0
  67. wbcore/contrib/directory/migrations/0011_person_description_person_i18n.py +24 -0
  68. wbcore/contrib/directory/migrations/0012_alter_person_managers.py +20 -0
  69. wbcore/contrib/directory/migrations/0013_alter_clientmanagerrelationship_options.py +17 -0
  70. wbcore/contrib/directory/models/contacts.py +2 -2
  71. wbcore/contrib/directory/models/entries.py +31 -5
  72. wbcore/contrib/directory/models/relationships.py +31 -35
  73. wbcore/contrib/directory/permissions.py +6 -0
  74. wbcore/contrib/directory/serializers/companies.py +16 -8
  75. wbcore/contrib/directory/serializers/contacts.py +8 -8
  76. wbcore/contrib/directory/serializers/entries.py +26 -15
  77. wbcore/contrib/directory/serializers/entry_representations.py +4 -2
  78. wbcore/contrib/directory/serializers/persons.py +12 -10
  79. wbcore/contrib/directory/serializers/relationships.py +2 -2
  80. wbcore/contrib/directory/tests/conftest.py +2 -0
  81. wbcore/contrib/directory/tests/disable_signals.py +11 -1
  82. wbcore/contrib/directory/tests/signals.py +2 -2
  83. wbcore/contrib/directory/tests/test_models.py +88 -66
  84. wbcore/contrib/directory/tests/test_serializers.py +1 -1
  85. wbcore/contrib/directory/tests/test_viewsets.py +8 -8
  86. wbcore/contrib/directory/viewsets/buttons/__init__.py +1 -1
  87. wbcore/contrib/directory/viewsets/buttons/relationships.py +32 -0
  88. wbcore/contrib/directory/viewsets/contacts.py +6 -6
  89. wbcore/contrib/directory/viewsets/display/__init__.py +1 -1
  90. wbcore/contrib/directory/viewsets/display/contacts.py +1 -14
  91. wbcore/contrib/directory/viewsets/display/entries.py +68 -38
  92. wbcore/contrib/directory/viewsets/display/relationships.py +26 -50
  93. wbcore/contrib/directory/viewsets/endpoints/relationships.py +1 -26
  94. wbcore/contrib/directory/viewsets/entries.py +8 -6
  95. wbcore/contrib/directory/viewsets/previews/entries.py +3 -3
  96. wbcore/contrib/directory/viewsets/relationships.py +16 -2
  97. wbcore/contrib/directory/viewsets/titles/relationships.py +2 -3
  98. wbcore/contrib/documents/filters.py +0 -2
  99. wbcore/contrib/documents/locale/de/LC_MESSAGES/django.po +103 -94
  100. wbcore/contrib/documents/locale/de/LC_MESSAGES/django.po.translated +285 -0
  101. wbcore/contrib/documents/locale/en/LC_MESSAGES/django.po +271 -0
  102. wbcore/contrib/documents/locale/fr/LC_MESSAGES/django.po +270 -0
  103. wbcore/contrib/documents/tests/test_models.py +32 -28
  104. wbcore/contrib/documents/viewsets/endpoints/shareable_links.py +2 -21
  105. wbcore/contrib/dynamic_preferences/types.py +108 -0
  106. wbcore/contrib/dynamic_preferences/viewsets.py +27 -0
  107. wbcore/contrib/example_app/filters/event.py +3 -1
  108. wbcore/contrib/example_app/filters/match.py +1 -1
  109. wbcore/contrib/example_app/models.py +91 -22
  110. wbcore/contrib/example_app/serializers/person_team.py +4 -4
  111. wbcore/contrib/example_app/templates/example_app/embedded_view.html +19 -0
  112. wbcore/contrib/example_app/tests/e2e/test_teams.py +1 -1
  113. wbcore/contrib/example_app/tests/test_models/test_match.py +17 -7
  114. wbcore/contrib/example_app/urls.py +2 -0
  115. wbcore/contrib/example_app/views.py +7 -0
  116. wbcore/contrib/example_app/viewsets/displays/team.py +23 -4
  117. wbcore/contrib/example_app/viewsets/menu/menus.py +1 -1
  118. wbcore/contrib/example_app/viewsets/menus.py +1 -1
  119. wbcore/contrib/geography/tests/conftest.py +14 -0
  120. wbcore/contrib/geography/tests/test_models.py +23 -8
  121. wbcore/contrib/geography/tests/test_viewsets.py +96 -2
  122. wbcore/contrib/guardian/tests/test_model_mixins.py +3 -4
  123. wbcore/contrib/guardian/tests/test_tasks.py +9 -9
  124. wbcore/contrib/guardian/tests/test_viewsets.py +2 -2
  125. wbcore/contrib/guardian/viewsets/configs/__init__.py +1 -1
  126. wbcore/contrib/guardian/viewsets/configs/buttons.py +9 -0
  127. wbcore/contrib/guardian/viewsets/configs/endpoints.py +7 -0
  128. wbcore/contrib/guardian/viewsets/viewsets.py +2 -0
  129. wbcore/contrib/i18n/__init__.py +2 -0
  130. wbcore/contrib/i18n/buttons.py +33 -0
  131. wbcore/contrib/i18n/serializers/__init__.py +0 -0
  132. wbcore/contrib/i18n/serializers/fields.py +20 -0
  133. wbcore/contrib/i18n/serializers/mixins.py +13 -0
  134. wbcore/contrib/i18n/tests/conftest.py +11 -0
  135. wbcore/contrib/i18n/tests/test_viewsets.py +67 -0
  136. wbcore/contrib/i18n/translation.py +140 -0
  137. wbcore/contrib/i18n/viewsets.py +36 -0
  138. wbcore/contrib/icons/backends/default.py +1 -0
  139. wbcore/contrib/icons/backends/material.py +1 -0
  140. wbcore/contrib/icons/icons.py +5 -8
  141. wbcore/contrib/io/admin.py +1 -0
  142. wbcore/contrib/io/backends/mail.py +3 -2
  143. wbcore/contrib/io/backends/utils.py +14 -17
  144. wbcore/contrib/io/exceptions.py +8 -0
  145. wbcore/contrib/io/factories.py +1 -1
  146. wbcore/contrib/io/import_export/backends/mail.py +1 -0
  147. wbcore/contrib/io/import_export/backends/sftp.py +29 -20
  148. wbcore/contrib/io/import_export/backends/stream.py +2 -2
  149. wbcore/contrib/io/import_export/parsers/__init__.py +0 -0
  150. wbcore/contrib/io/import_export/parsers/base_csv.py +36 -0
  151. wbcore/contrib/io/import_export/parsers/resources.py +50 -0
  152. wbcore/contrib/io/imports.py +33 -25
  153. wbcore/contrib/io/locale/de/LC_MESSAGES/django.po +114 -22
  154. wbcore/contrib/io/locale/de/LC_MESSAGES/django.po.translated +103 -0
  155. wbcore/contrib/io/locale/en/LC_MESSAGES/django.po +138 -0
  156. wbcore/contrib/io/locale/fr/LC_MESSAGES/django.po +138 -0
  157. wbcore/contrib/io/migrations/0008_importsource_resource_kwargs.py +18 -0
  158. wbcore/contrib/io/models.py +65 -45
  159. wbcore/contrib/io/resources.py +0 -6
  160. wbcore/contrib/io/serializers.py +2 -2
  161. wbcore/contrib/io/signals.py +4 -0
  162. wbcore/contrib/io/tests/test_backends.py +19 -13
  163. wbcore/contrib/io/tests/test_exports.py +1 -1
  164. wbcore/contrib/io/tests/test_imports.py +1 -1
  165. wbcore/contrib/io/tests/test_models.py +47 -14
  166. wbcore/contrib/io/tests/test_viewsets.py +271 -0
  167. wbcore/contrib/io/viewset_mixins.py +41 -54
  168. wbcore/contrib/notifications/admin.py +1 -0
  169. wbcore/contrib/notifications/apps.py +2 -1
  170. wbcore/contrib/notifications/backends/abstract_backend.py +2 -4
  171. wbcore/contrib/notifications/backends/firebase/backends.py +5 -2
  172. wbcore/contrib/notifications/dispatch.py +18 -7
  173. wbcore/contrib/notifications/factories/notification_types.py +1 -0
  174. wbcore/contrib/notifications/locale/de/LC_MESSAGES/django.po +25 -19
  175. wbcore/contrib/notifications/locale/de/LC_MESSAGES/django.po.translated +63 -0
  176. wbcore/contrib/notifications/locale/en/LC_MESSAGES/django.po +61 -0
  177. wbcore/contrib/notifications/locale/fr/LC_MESSAGES/django.po +62 -0
  178. wbcore/contrib/notifications/migrations/0008_notificationtype_is_lock.py +18 -0
  179. wbcore/contrib/notifications/migrations/0009_alter_notificationtypesetting_options_and_more.py +32 -0
  180. wbcore/contrib/notifications/models/notification_types.py +67 -24
  181. wbcore/contrib/notifications/serializers/notification_types.py +16 -1
  182. wbcore/contrib/notifications/tests/test_models/test_tokens.py +8 -0
  183. wbcore/contrib/notifications/tests/test_serializers/test_notification_types.py +5 -0
  184. wbcore/contrib/notifications/tests/test_viewsets/test_notification_types.py +3 -5
  185. wbcore/contrib/notifications/utils.py +3 -2
  186. wbcore/contrib/notifications/viewsets/configs/notification_types.py +28 -6
  187. wbcore/contrib/notifications/viewsets/menus.py +1 -1
  188. wbcore/contrib/notifications/viewsets/notification_types.py +12 -2
  189. wbcore/contrib/pandas/fields.py +38 -10
  190. wbcore/contrib/pandas/filters.py +4 -1
  191. wbcore/contrib/pandas/filterset.py +8 -7
  192. wbcore/contrib/pandas/tests/test_fields/test_number_fields.py +2 -7
  193. wbcore/contrib/pandas/utils.py +1 -1
  194. wbcore/contrib/pandas/views.py +14 -13
  195. wbcore/contrib/tags/models/tags.py +4 -1
  196. wbcore/contrib/workflow/factories/display.py +2 -2
  197. wbcore/contrib/workflow/factories/transition.py +16 -15
  198. wbcore/contrib/workflow/locale/de/LC_MESSAGES/django.po +457 -566
  199. wbcore/contrib/workflow/locale/de/LC_MESSAGES/django.po.translated +1326 -0
  200. wbcore/contrib/workflow/locale/en/LC_MESSAGES/django.po +1102 -0
  201. wbcore/contrib/workflow/locale/fr/LC_MESSAGES/django.po +1114 -0
  202. wbcore/contrib/workflow/models/data.py +7 -4
  203. wbcore/contrib/workflow/models/process.py +2 -2
  204. wbcore/contrib/workflow/models/step.py +57 -15
  205. wbcore/contrib/workflow/serializers/data.py +8 -8
  206. wbcore/contrib/workflow/serializers/process.py +3 -2
  207. wbcore/contrib/workflow/tests/conftest.py +224 -0
  208. wbcore/contrib/workflow/tests/test_dispatch.py +82 -77
  209. wbcore/contrib/workflow/tests/test_displays.py +10 -88
  210. wbcore/contrib/workflow/tests/test_filters.py +57 -40
  211. wbcore/contrib/workflow/tests/test_models/step/test_decision_step.py +71 -68
  212. wbcore/contrib/workflow/tests/test_models/step/test_email_step.py +78 -38
  213. wbcore/contrib/workflow/tests/test_models/step/test_finish_step.py +152 -90
  214. wbcore/contrib/workflow/tests/test_models/step/test_join_step.py +100 -110
  215. wbcore/contrib/workflow/tests/test_models/step/test_step.py +168 -33
  216. wbcore/contrib/workflow/tests/test_models/test_condition.py +1 -1
  217. wbcore/contrib/workflow/tests/test_models/test_workflow.py +3 -3
  218. wbcore/contrib/workflow/tests/test_serializers.py +172 -150
  219. wbcore/contrib/workflow/tests/test_viewsets.py +264 -323
  220. wbcore/contrib/workflow/tests/test_workflow_assignees.py +215 -205
  221. wbcore/contrib/workflow/viewsets/process.py +4 -1
  222. wbcore/contrib/workflow/workflows/assignees.py +12 -7
  223. wbcore/dynamic_preferences_registry.py +102 -0
  224. wbcore/enums.py +2 -51
  225. wbcore/filters/fields/choices.py +4 -6
  226. wbcore/filters/fields/content_type.py +15 -4
  227. wbcore/filters/fields/datetime.py +50 -25
  228. wbcore/filters/fields/models.py +18 -9
  229. wbcore/filters/fields/numbers.py +9 -8
  230. wbcore/filters/filterset.py +27 -6
  231. wbcore/filters/mixins.py +41 -42
  232. wbcore/forms.py +6 -6
  233. wbcore/fsm/markdown_extensions.py +1 -1
  234. wbcore/fsm/mixins.py +20 -6
  235. wbcore/locale/de/LC_MESSAGES/django.po +982 -397
  236. wbcore/locale/de/LC_MESSAGES/django.po.translated +1580 -0
  237. wbcore/locale/en/LC_MESSAGES/django.po +1234 -0
  238. wbcore/locale/fr/LC_MESSAGES/django.po +1235 -0
  239. wbcore/markdown/models.py +8 -5
  240. wbcore/markdown/views.py +1 -1
  241. wbcore/menus/menus.py +2 -2
  242. wbcore/metadata/configs/buttons/bases.py +10 -7
  243. wbcore/metadata/configs/buttons/buttons.py +2 -1
  244. wbcore/metadata/configs/buttons/enums.py +50 -0
  245. wbcore/metadata/configs/buttons/view_config.py +13 -46
  246. wbcore/metadata/configs/display/display.py +2 -2
  247. wbcore/metadata/configs/display/formatting.py +6 -9
  248. wbcore/metadata/configs/display/instance_display/display.py +5 -2
  249. wbcore/metadata/configs/display/instance_display/pages.py +1 -1
  250. wbcore/metadata/configs/display/instance_display/shortcuts.py +1 -1
  251. wbcore/metadata/configs/display/list_display.py +54 -40
  252. wbcore/metadata/configs/display/models.py +6 -0
  253. wbcore/metadata/configs/display/view_config.py +11 -9
  254. wbcore/metadata/configs/endpoints.py +11 -4
  255. wbcore/metadata/configs/fields.py +6 -1
  256. wbcore/metadata/configs/filter_fields.py +12 -13
  257. wbcore/metadata/configs/identifiers.py +3 -1
  258. wbcore/metadata/tests/test_buttons.py +13 -16
  259. wbcore/models/fields.py +2 -2
  260. wbcore/pagination.py +1 -2
  261. wbcore/permissions/permissions.py +2 -2
  262. wbcore/permissions/utils.py +2 -2
  263. wbcore/release_notes/display.py +2 -8
  264. wbcore/release_notes/serializers.py +2 -9
  265. wbcore/release_notes/viewsets.py +8 -2
  266. wbcore/reversion/viewsets/titles.py +4 -3
  267. wbcore/serializers/__init__.py +2 -0
  268. wbcore/serializers/fields/__init__.py +2 -1
  269. wbcore/serializers/fields/boolean.py +1 -1
  270. wbcore/serializers/fields/choice.py +28 -4
  271. wbcore/serializers/fields/datetime.py +45 -36
  272. wbcore/serializers/fields/fields.py +1 -1
  273. wbcore/serializers/fields/fsm.py +1 -1
  274. wbcore/serializers/fields/list.py +2 -5
  275. wbcore/serializers/fields/mixins.py +24 -11
  276. wbcore/serializers/fields/number.py +6 -23
  277. wbcore/serializers/fields/other.py +2 -10
  278. wbcore/serializers/fields/related.py +4 -6
  279. wbcore/serializers/fields/text.py +1 -1
  280. wbcore/serializers/fields/types.py +2 -0
  281. wbcore/serializers/serializers.py +12 -3
  282. wbcore/signals/__init__.py +1 -0
  283. wbcore/signals/clone.py +4 -0
  284. wbcore/signals/models.py +2 -6
  285. wbcore/tasks.py +2 -2
  286. wbcore/templates/wbcore/email_base_template.html +3 -3
  287. wbcore/test/e2e_helpers_methods/e2e_checks.py +10 -4
  288. wbcore/test/e2e_helpers_methods/e2e_helper_methods.py +4 -2
  289. wbcore/test/mixins.py +52 -102
  290. wbcore/test/tests.py +6 -9
  291. wbcore/test/utils.py +3 -4
  292. wbcore/tests/e2e/test_e2e.py +2 -2
  293. wbcore/tests/test_cache/test_decorators.py +4 -7
  294. wbcore/tests/test_configs.py +2 -5
  295. wbcore/tests/test_enums.py +2 -1
  296. wbcore/tests/test_fields/test_choice_fields.py +9 -1
  297. wbcore/tests/test_fields/test_number_fields.py +7 -15
  298. wbcore/tests/test_fields/test_other_fields.py +1 -2
  299. wbcore/tests/test_filters/test_mixins.py +35 -35
  300. wbcore/tests/test_list_display.py +0 -2
  301. wbcore/tests/test_models/test_mixins.py +1 -1
  302. wbcore/tests/test_utils/test_date.py +1 -1
  303. wbcore/tests/test_utils/test_date_builder.py +25 -1
  304. wbcore/tests/test_utils/test_primary.py +1 -1
  305. wbcore/urls.py +4 -0
  306. wbcore/utils/date.py +18 -2
  307. wbcore/utils/figures.py +2 -2
  308. wbcore/utils/models.py +21 -4
  309. wbcore/utils/reportlab.py +7 -0
  310. wbcore/utils/rrules.py +3 -1
  311. wbcore/utils/string_loader.py +1 -1
  312. wbcore/utils/strings.py +3 -3
  313. wbcore/utils/views.py +8 -3
  314. wbcore/viewsets/mixins.py +9 -4
  315. {wbcore-1.46.0.dist-info → wbcore-1.58.2.dist-info}/METADATA +9 -5
  316. {wbcore-1.46.0.dist-info → wbcore-1.58.2.dist-info}/RECORD +317 -271
  317. wbcore/contrib/geography/tests/test_serializers.py +0 -7
  318. wbcore/contrib/geography/tests/tests.py +0 -13
  319. wbcore/contrib/io/tests/tests.py +0 -19
  320. wbcore/contrib/workflow/tests/tests.py +0 -25
  321. {wbcore-1.46.0.dist-info → wbcore-1.58.2.dist-info}/WHEEL +0 -0
@@ -23,7 +23,10 @@ class TestStep:
23
23
  process = process_factory(workflow=step.workflow)
24
24
  activate_step(step.pk, process.pk)
25
25
  process_step_qs = ProcessStep.objects.filter(
26
- state=ProcessStep.StepState.ACTIVE, process=process, step=step, status=step.status
26
+ state=ProcessStep.StepState.ACTIVE,
27
+ process=process,
28
+ step=step,
29
+ status=step.status,
27
30
  )
28
31
  assert process_step_qs.count() == 1
29
32
  assert mock_run.call_args.args == (process_step_qs.first(),)
@@ -34,7 +37,10 @@ class TestStep:
34
37
  process = process_factory(workflow=step.workflow, instance=None, instance_id=None)
35
38
  activate_step(step.pk, process.pk)
36
39
  process_step_qs = ProcessStep.objects.filter(
37
- state=ProcessStep.StepState.ACTIVE, process=process, step=step, status=step.status
40
+ state=ProcessStep.StepState.ACTIVE,
41
+ process=process,
42
+ step=step,
43
+ status=step.status,
38
44
  )
39
45
  assert process_step_qs.count() == 1
40
46
  assert mock_run.call_args.args == (process_step_qs.first(),)
@@ -45,7 +51,10 @@ class TestStep:
45
51
  process = process_factory(workflow=step.workflow)
46
52
  activate_step(step.pk, process.pk)
47
53
  process_step_qs = ProcessStep.objects.filter(
48
- state=ProcessStep.StepState.ACTIVE, process=process, step=step, status=step.status
54
+ state=ProcessStep.StepState.ACTIVE,
55
+ process=process,
56
+ step=step,
57
+ status=step.status,
49
58
  )
50
59
  assert process_step_qs.count() == 1
51
60
  assert mock_run.call_args.args == (process_step_qs.first(),)
@@ -88,7 +97,10 @@ class TestStep:
88
97
  process = process_factory(workflow=step.workflow)
89
98
  activate_step(step.pk, process.pk)
90
99
  process_step_qs = ProcessStep.objects.filter(
91
- state=ProcessStep.StepState.ACTIVE, process=process, step=step, status=step.status
100
+ state=ProcessStep.StepState.ACTIVE,
101
+ process=process,
102
+ step=step,
103
+ status=step.status,
92
104
  )
93
105
  assert process_step_qs.count() == 1
94
106
  assert Person.objects.get(id=process.instance.pk).first_name == step.status
@@ -100,7 +112,10 @@ class TestStep:
100
112
  process = process_factory(workflow=step.workflow)
101
113
  activate_step(step.pk, process.pk)
102
114
  process_step_qs = ProcessStep.objects.filter(
103
- state=ProcessStep.StepState.ACTIVE, process=process, step=step, status=step.status
115
+ state=ProcessStep.StepState.ACTIVE,
116
+ process=process,
117
+ step=step,
118
+ status=step.status,
104
119
  )
105
120
  assert process_step_qs.count() == 1
106
121
  assert Person.objects.get(id=process.instance.pk).first_name == step.status
@@ -112,7 +127,10 @@ class TestStep:
112
127
  process = process_factory(workflow=step.workflow)
113
128
  activate_step(step.pk, process.pk)
114
129
  process_step_qs = ProcessStep.objects.filter(
115
- state=ProcessStep.StepState.ACTIVE, process=process, step=step, status=step.status
130
+ state=ProcessStep.StepState.ACTIVE,
131
+ process=process,
132
+ step=step,
133
+ status=step.status,
116
134
  )
117
135
  assert process_step_qs.count() == 1
118
136
  assert Person.objects.get(id=process.instance.pk).first_name == step.status
@@ -124,7 +142,10 @@ class TestStep:
124
142
  process = process_factory(workflow=step.workflow)
125
143
  activate_step(step.pk, process.pk)
126
144
  process_step_qs = ProcessStep.objects.filter(
127
- state=ProcessStep.StepState.ACTIVE, process=process, step=step, status=step.status
145
+ state=ProcessStep.StepState.ACTIVE,
146
+ process=process,
147
+ step=step,
148
+ status=step.status,
128
149
  )
129
150
  assert process_step_qs.count() == 1
130
151
  assert Person.objects.get(id=process.instance.pk).first_name == step.status
@@ -136,7 +157,10 @@ class TestStep:
136
157
  process = process_factory(workflow=step.workflow)
137
158
  activate_step(step.pk, process.pk)
138
159
  process_step_qs = ProcessStep.objects.filter(
139
- state=ProcessStep.StepState.ACTIVE, process=process, step=step, status=step.status
160
+ state=ProcessStep.StepState.ACTIVE,
161
+ process=process,
162
+ step=step,
163
+ status=step.status,
140
164
  )
141
165
  assert process_step_qs.count() == 1
142
166
  assert Person.objects.get(id=process.instance.pk).first_name == step.status
@@ -146,12 +170,25 @@ class TestStep:
146
170
  def test_activate_join_step(self, mock_run, process_step_factory, join_step_factory, process_factory):
147
171
  step = join_step_factory()
148
172
  process = process_factory(workflow=step.workflow)
149
- process_step_factory(state=ProcessStep.StepState.WAITING, step=step, status=step.status, process=process)
150
- process_step_factory(state=ProcessStep.StepState.WAITING, step=step, status=step.status, finished=None)
173
+ process_step_factory(
174
+ state=ProcessStep.StepState.WAITING,
175
+ step=step,
176
+ status=step.status,
177
+ process=process,
178
+ )
179
+ process_step_factory(
180
+ state=ProcessStep.StepState.WAITING,
181
+ step=step,
182
+ status=step.status,
183
+ finished=None,
184
+ )
151
185
  process_step_factory()
152
186
  activate_step(step.pk, process.pk)
153
187
  process_step_qs = ProcessStep.objects.filter(
154
- state=ProcessStep.StepState.ACTIVE, process=process, step=step, status=step.status
188
+ state=ProcessStep.StepState.ACTIVE,
189
+ process=process,
190
+ step=step,
191
+ status=step.status,
155
192
  )
156
193
  assert process_step_qs.count() == 1
157
194
  assert Person.objects.get(id=process.instance.pk).first_name == step.status
@@ -164,15 +201,26 @@ class TestStep:
164
201
  step = join_step_factory()
165
202
  process = process_factory(workflow=step.workflow)
166
203
  process_step_factory(
167
- state=ProcessStep.StepState.WAITING, step=step, status=step.status, process=process, finished=None
204
+ state=ProcessStep.StepState.WAITING,
205
+ step=step,
206
+ status=step.status,
207
+ process=process,
208
+ finished=None,
168
209
  )
169
210
  process_step_factory(
170
- state=ProcessStep.StepState.WAITING, step=step, status=step.status, process=process, finished=None
211
+ state=ProcessStep.StepState.WAITING,
212
+ step=step,
213
+ status=step.status,
214
+ process=process,
215
+ finished=None,
171
216
  )
172
217
  process_step_factory()
173
218
  activate_step(step.pk, process.pk)
174
219
  process_step_qs = ProcessStep.objects.filter(
175
- state=ProcessStep.StepState.ACTIVE, process=process, step=step, status=step.status
220
+ state=ProcessStep.StepState.ACTIVE,
221
+ process=process,
222
+ step=step,
223
+ status=step.status,
176
224
  )
177
225
  assert process_step_qs.count() == 1
178
226
  assert Person.objects.get(id=process.instance.pk).first_name == step.status
@@ -182,14 +230,26 @@ class TestStep:
182
230
  def test_activate_waiting_join_step(self, mock_run, process_step_factory, join_step_factory, process_factory):
183
231
  step = join_step_factory()
184
232
  process = process_factory(workflow=step.workflow)
185
- process_step_factory(state=ProcessStep.StepState.WAITING, step=step, status=step.status, process=process)
233
+ process_step_factory(
234
+ state=ProcessStep.StepState.WAITING,
235
+ step=step,
236
+ status=step.status,
237
+ process=process,
238
+ )
186
239
  waiting_process_step = process_step_factory(
187
- state=ProcessStep.StepState.WAITING, step=step, status=step.status, process=process, finished=None
240
+ state=ProcessStep.StepState.WAITING,
241
+ step=step,
242
+ status=step.status,
243
+ process=process,
244
+ finished=None,
188
245
  )
189
246
  process_step_factory()
190
247
  activate_step(step.pk, process.pk)
191
248
  assert not ProcessStep.objects.filter(
192
- state=ProcessStep.StepState.ACTIVE, process=process, step=step, status=step.status
249
+ state=ProcessStep.StepState.ACTIVE,
250
+ process=process,
251
+ step=step,
252
+ status=step.status,
193
253
  ).exists()
194
254
  assert Person.objects.get(id=process.instance.pk).first_name == step.status
195
255
  assert str(mock_run.call_args.args[0].pk) == waiting_process_step.pk
@@ -208,16 +268,32 @@ class TestStep:
208
268
  transition = transition_factory(to_step=step)
209
269
  assert list(step.get_incoming_transitions()) == [transition]
210
270
 
211
- def test_get_previous_steps(self, random_child_step_factory, transition_factory):
212
- step = random_child_step_factory()
213
- transition1 = transition_factory(to_step=step)
214
- transition2 = transition_factory(to_step=step)
215
- transition_factory(from_step=step)
271
+ def test_get_previous_steps(
272
+ self,
273
+ join_step_factory,
274
+ split_step_factory,
275
+ finish_step_factory,
276
+ transition_factory,
277
+ ):
278
+ to_step = join_step_factory()
279
+ from_step = split_step_factory()
280
+ transition1 = transition_factory(to_step=to_step, from_step=from_step)
281
+ transition2 = transition_factory(to_step=to_step, from_step=from_step)
282
+ transition_factory(to_step=finish_step_factory(), from_step=to_step)
216
283
  transition_factory()
217
- assert set(step.get_previous_steps()) == {transition1.from_step, transition2.from_step}
284
+ previous_steps = to_step.get_previous_steps()
285
+ previous_steps = [step.id for step in previous_steps]
286
+ assert set(previous_steps) == {
287
+ transition1.from_step.id,
288
+ transition2.from_step.id,
289
+ }
218
290
 
219
291
  def test_get_all_valid_outgoing_transitions(
220
- self, random_child_step_factory, transition_factory, condition_factory, process_step_factory
292
+ self,
293
+ random_child_step_factory,
294
+ transition_factory,
295
+ condition_factory,
296
+ process_step_factory,
221
297
  ):
222
298
  person = PersonFactory()
223
299
  step = random_child_step_factory()
@@ -247,7 +323,10 @@ class TestStep:
247
323
  valid_transition_without_condition = transition_factory(from_step=step, to_step__workflow=step.workflow)
248
324
  process_step = process_step_factory(step=step, process__instance=person)
249
325
  transitions = step.get_all_valid_outgoing_transitions(process_step)
250
- assert set(transitions) == {valid_transition, valid_transition_without_condition}
326
+ assert set(transitions) == {
327
+ valid_transition,
328
+ valid_transition_without_condition,
329
+ }
251
330
 
252
331
  def test_get_assigned_group(self, random_child_step_factory):
253
332
  random_step = random_child_step_factory(exclude_factories=[UserStepFactory])
@@ -343,7 +422,11 @@ class TestStep:
343
422
 
344
423
  @patch("wbcore.contrib.workflow.models.step.Step.start_next_step")
345
424
  def test_execute_single_next_step(
346
- self, mock_next, process_step_factory, transition_factory, random_child_step_factory
425
+ self,
426
+ mock_next,
427
+ process_step_factory,
428
+ transition_factory,
429
+ random_child_step_factory,
347
430
  ):
348
431
  step = random_child_step_factory()
349
432
  process_step = process_step_factory(step=step)
@@ -354,7 +437,11 @@ class TestStep:
354
437
 
355
438
  @patch("wbcore.contrib.workflow.models.step.Step.set_failed")
356
439
  def test_execute_single_next_step_no_transitions(
357
- self, mock_failed, process_step_factory, transition_factory, random_child_step_factory
440
+ self,
441
+ mock_failed,
442
+ process_step_factory,
443
+ transition_factory,
444
+ random_child_step_factory,
358
445
  ):
359
446
  step = random_child_step_factory(exclude_factories=[UserStepFactory])
360
447
  process_step = process_step_factory(step=step)
@@ -364,7 +451,11 @@ class TestStep:
364
451
 
365
452
  @patch("wbcore.contrib.workflow.models.step.Step.set_failed")
366
453
  def test_execute_single_next_step_multiple_transitions(
367
- self, mock_failed, process_step_factory, transition_factory, random_child_step_factory
454
+ self,
455
+ mock_failed,
456
+ process_step_factory,
457
+ transition_factory,
458
+ random_child_step_factory,
368
459
  ):
369
460
  step = random_child_step_factory(exclude_factories=[UserStepFactory])
370
461
  process_step = process_step_factory(step=step)
@@ -403,7 +494,10 @@ class TestStep:
403
494
  process_step = process_step_factory()
404
495
  Step.start_next_step(process_step, transition)
405
496
  assert mock_finish.call_args.args == (process_step,)
406
- assert mock_activate.call_args.args == (transition.to_step.pk, process_step.process.pk)
497
+ assert mock_activate.call_args.args == (
498
+ transition.to_step.pk,
499
+ process_step.process.pk,
500
+ )
407
501
 
408
502
  @patch("wbcore.contrib.workflow.models.process.Process.set_failed")
409
503
  def test_process_can_finish_no_active(self, mock_failed, process_step_factory):
@@ -417,7 +511,11 @@ class TestStep:
417
511
 
418
512
  @patch("wbcore.contrib.workflow.models.process.Process.set_failed")
419
513
  def test_process_can_finish_no_join_steps(
420
- self, mock_failed, process_step_factory, random_child_step_factory, process_factory
514
+ self,
515
+ mock_failed,
516
+ process_step_factory,
517
+ random_child_step_factory,
518
+ process_factory,
421
519
  ):
422
520
  step = random_child_step_factory(exclude_factories=[JoinStepFactory])
423
521
  process = process_factory(workflow=step.workflow)
@@ -495,7 +593,19 @@ class TestStep:
495
593
  process = process_factory(workflow=workflow)
496
594
  process_step_factory(step=step12, state=ProcessStep.StepState.FAILED, process=process)
497
595
  process_step_factory(step=step11, state=ProcessStep.StepState.ACTIVE, process=process)
498
- for step in [step1, step2, step3, step4, step5, step6, step7, step8, step9, step10, step14]:
596
+ for step in [
597
+ step1,
598
+ step2,
599
+ step3,
600
+ step4,
601
+ step5,
602
+ step6,
603
+ step7,
604
+ step8,
605
+ step9,
606
+ step10,
607
+ step14,
608
+ ]:
499
609
  process_step_factory(step=step, state=ProcessStep.StepState.FINISHED, process=process)
500
610
  process_can_finish(process.pk)
501
611
  assert not mock_failed.called
@@ -555,7 +665,21 @@ class TestStep:
555
665
  process = process_factory(workflow=workflow)
556
666
  process_step_factory(step=step8, state=ProcessStep.StepState.FAILED, process=process)
557
667
  process_step_factory(step=step14, state=ProcessStep.StepState.WAITING, process=process)
558
- for step in [step1, step2, step3, step4, step5, step6, step7, step9, step10, step11, step12, step13, step15]:
668
+ for step in [
669
+ step1,
670
+ step2,
671
+ step3,
672
+ step4,
673
+ step5,
674
+ step6,
675
+ step7,
676
+ step9,
677
+ step10,
678
+ step11,
679
+ step12,
680
+ step13,
681
+ step15,
682
+ ]:
559
683
  process_step_factory(step=step, state=ProcessStep.StepState.FINISHED, process=process)
560
684
  process_can_finish(process.pk)
561
685
  assert mock_failed.called
@@ -615,7 +739,18 @@ class TestStep:
615
739
  process = process_factory(workflow=workflow)
616
740
  process_step_factory(step=step6, state=ProcessStep.StepState.FAILED, process=process)
617
741
  process_step_factory(step=step15, state=ProcessStep.StepState.ACTIVE, process=process)
618
- for step in [step1, step2, step3, step4, step5, step10, step11, step12, step13, step15]:
742
+ for step in [
743
+ step1,
744
+ step2,
745
+ step3,
746
+ step4,
747
+ step5,
748
+ step10,
749
+ step11,
750
+ step12,
751
+ step13,
752
+ step15,
753
+ ]:
619
754
  process_step_factory(step=step, state=ProcessStep.StepState.FINISHED, process=process)
620
755
  process_can_finish(process.pk)
621
756
  assert mock_failed.called
@@ -10,7 +10,7 @@ class TestCondition:
10
10
  def test_errors_satisfied_not_called(self, condition_factory):
11
11
  condition = condition_factory()
12
12
  with pytest.raises(ValueError):
13
- condition.errors
13
+ assert condition.errors == []
14
14
 
15
15
  def test_errors(self, condition_factory):
16
16
  condition = condition_factory()
@@ -48,9 +48,9 @@ class TestWorkflow:
48
48
  default_value = "Test"
49
49
  data2 = data_factory(workflow=workflow, default=default_value)
50
50
  start_step = start_step_factory()
51
- workflow_site.registered_model_classes_serializer_map[
52
- Person
53
- ] = "wbcore.contrib.directory.serializers.PersonModelSerializer"
51
+ workflow_site.registered_model_classes_serializer_map[Person] = (
52
+ "wbcore.contrib.directory.serializers.PersonModelSerializer"
53
+ )
54
54
  workflow.start_workflow(start_step, attached_person)
55
55
  process_qs = Process.objects.filter(
56
56
  workflow=workflow,