wbcore 2.2.1__py2.py3-none-any.whl → 2.2.4__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 (143) hide show
  1. wbcore/contrib/agenda/locale/de/LC_MESSAGES/django.po +113 -0
  2. wbcore/contrib/agenda/static/agenda/markdown/documentation/building.md +11 -0
  3. wbcore/contrib/agenda/static/agenda/markdown/documentation/conferenceroom.md +20 -0
  4. wbcore/contrib/authentication/fixtures/authentication.json +62 -0
  5. wbcore/contrib/authentication/locale/de/LC_MESSAGES/django.po +610 -0
  6. wbcore/contrib/authentication/templates/activate_confirm.html +12 -0
  7. wbcore/contrib/authentication/templates/base.html +135 -0
  8. wbcore/contrib/authentication/templates/email_base_template.html +335 -0
  9. wbcore/contrib/authentication/templates/password_reset_done.html +13 -0
  10. wbcore/contrib/authentication/templates/password_reset_email.html +11 -0
  11. wbcore/contrib/authentication/templates/password_reset_email_html.html +43 -0
  12. wbcore/contrib/authentication/templates/password_reset_form.html +23 -0
  13. wbcore/contrib/authentication/templates/password_reset_sent.html +11 -0
  14. wbcore/contrib/authentication/templates/reset_password.html +15 -0
  15. wbcore/contrib/authentication/templates/user_registration_email.html +37 -0
  16. wbcore/contrib/color/admin.py +28 -0
  17. wbcore/contrib/color/apps.py +5 -0
  18. wbcore/contrib/color/enums.py +17 -0
  19. wbcore/contrib/color/factories.py +10 -0
  20. wbcore/contrib/color/fields.py +29 -0
  21. wbcore/contrib/color/forms.py +13 -0
  22. wbcore/contrib/color/models.py +62 -0
  23. wbcore/contrib/color/tests/conftest.py +10 -0
  24. wbcore/contrib/color/tests/test_color_models.py +61 -0
  25. wbcore/contrib/color/tests/test_fields.py +25 -0
  26. wbcore/contrib/currency/fixtures/currency.yaml +1014 -0
  27. wbcore/contrib/currency/fixtures/currency_fx_rate.yaml +73585 -0
  28. wbcore/contrib/directory/fixtures/directory.json +3924 -0
  29. wbcore/contrib/directory/locale/de/LC_MESSAGES/django.po +1686 -0
  30. wbcore/contrib/directory/static/directory/markdown/documentation/address.md +38 -0
  31. wbcore/contrib/directory/static/directory/markdown/documentation/banking.md +54 -0
  32. wbcore/contrib/directory/static/directory/markdown/documentation/bankingentry.md +38 -0
  33. wbcore/contrib/directory/static/directory/markdown/documentation/clientmanagerrelationship.md +42 -0
  34. wbcore/contrib/directory/static/directory/markdown/documentation/company.md +52 -0
  35. wbcore/contrib/directory/static/directory/markdown/documentation/companytype.md +2 -0
  36. wbcore/contrib/directory/static/directory/markdown/documentation/customerstatus.md +2 -0
  37. wbcore/contrib/directory/static/directory/markdown/documentation/email.md +20 -0
  38. wbcore/contrib/directory/static/directory/markdown/documentation/employeecompany.md +34 -0
  39. wbcore/contrib/directory/static/directory/markdown/documentation/employerperson.md +43 -0
  40. wbcore/contrib/directory/static/directory/markdown/documentation/person.md +61 -0
  41. wbcore/contrib/directory/static/directory/markdown/documentation/position.md +2 -0
  42. wbcore/contrib/directory/static/directory/markdown/documentation/relationshiptype.md +2 -0
  43. wbcore/contrib/directory/static/directory/markdown/documentation/socialmedia.md +23 -0
  44. wbcore/contrib/directory/static/directory/markdown/documentation/specialization.md +2 -0
  45. wbcore/contrib/directory/static/directory/markdown/documentation/systememployee.md +31 -0
  46. wbcore/contrib/directory/static/directory/markdown/documentation/telephone.md +23 -0
  47. wbcore/contrib/directory/static/directory/markdown/documentation/telephonesearch.md +26 -0
  48. wbcore/contrib/directory/static/directory/markdown/documentation/userisclient.md +14 -0
  49. wbcore/contrib/directory/static/directory/markdown/documentation/userismanager.md +28 -0
  50. wbcore/contrib/directory/static/directory/markdown/documentation/website.md +20 -0
  51. wbcore/contrib/documents/fixtures/docments.json +135 -0
  52. wbcore/contrib/documents/locale/de/LC_MESSAGES/django.po +272 -0
  53. wbcore/contrib/documents/static/documents/markdown/documentation/document_types.md +21 -0
  54. wbcore/contrib/documents/static/documents/markdown/documentation/documents.md +18 -0
  55. wbcore/contrib/documents/static/documents/markdown/documentation/shareablelink.md +28 -0
  56. wbcore/contrib/documents/static/documents/markdown/documentation/shareablelinkaccess.md +20 -0
  57. wbcore/contrib/documents/tests/conftest.py +30 -0
  58. wbcore/contrib/documents/tests/test_models.py +144 -0
  59. wbcore/contrib/example_app/fixtures/example_app.json +7425 -0
  60. wbcore/contrib/example_app/tests/test_models/test_event.py +87 -0
  61. wbcore/contrib/example_app/tests/test_models/test_match.py +210 -0
  62. wbcore/contrib/example_app/tests/test_models/test_others.py +159 -0
  63. wbcore/contrib/example_app/tests/test_serializers/test_league_serializer.py +34 -0
  64. wbcore/contrib/example_app/tests/test_serializers/test_match_serializer.py +134 -0
  65. wbcore/contrib/example_app/tests/test_serializers/test_role_serializer.py +13 -0
  66. wbcore/contrib/example_app/tests/test_serializers/test_sport_serializer.py +14 -0
  67. wbcore/contrib/example_app/tests/test_serializers/test_stadium_serializer.py +14 -0
  68. wbcore/contrib/example_app/tests/test_serializers/test_team_result_serializer.py +30 -0
  69. wbcore/contrib/example_app/tests/test_serializers/test_team_serializer.py +70 -0
  70. wbcore/contrib/example_app/tests/test_viewsets/test_event_viewset.py +162 -0
  71. wbcore/contrib/example_app/tests/test_viewsets/test_league_viewset.py +84 -0
  72. wbcore/contrib/example_app/tests/test_viewsets/test_match_viewset.py +65 -0
  73. wbcore/contrib/example_app/tests/test_viewsets/test_person_viewset.py +166 -0
  74. wbcore/contrib/example_app/tests/test_viewsets/test_role_viewset.py +75 -0
  75. wbcore/contrib/example_app/tests/test_viewsets/test_sport_viewset.py +75 -0
  76. wbcore/contrib/example_app/tests/test_viewsets/test_stadium_viewset.py +75 -0
  77. wbcore/contrib/example_app/tests/test_viewsets/test_team_viewset.py +92 -0
  78. wbcore/contrib/example_app/tests/test_viewsets/test_teamresult_viewset.py +58 -0
  79. wbcore/contrib/example_app/tests/test_viewsets/test_utils_viewsets.py +124 -0
  80. wbcore/contrib/geography/fixtures/geography.json +13454 -0
  81. wbcore/contrib/geography/static/geography/markdown/documentation/geography.md +16 -0
  82. wbcore/contrib/guardian/apps.py +6 -0
  83. wbcore/contrib/guardian/configurations.py +3 -0
  84. wbcore/contrib/guardian/filters.py +21 -0
  85. wbcore/contrib/guardian/tasks.py +10 -0
  86. wbcore/contrib/guardian/urls.py +12 -0
  87. wbcore/contrib/guardian/utils.py +124 -0
  88. wbcore/contrib/io/fixtures/io.json +145 -0
  89. wbcore/contrib/io/locale/de/LC_MESSAGES/django.po +52 -0
  90. wbcore/contrib/notifications/locale/de/LC_MESSAGES/django.po +60 -0
  91. wbcore/contrib/notifications/static/notifications/service-worker.js +1 -0
  92. wbcore/contrib/notifications/templates/notifications/notification_template.html +43 -0
  93. wbcore/contrib/notifications/viewsets/configs/notification_types.py +27 -0
  94. wbcore/contrib/notifications/viewsets/configs/notifications.py +85 -0
  95. wbcore/contrib/workflow/fixtures/workflow.json +612 -0
  96. wbcore/contrib/workflow/locale/de/LC_MESSAGES/django.po +1289 -0
  97. wbcore/contrib/workflow/static/workflow/markdown/documentation/assignedprocessstep.md +33 -0
  98. wbcore/contrib/workflow/static/workflow/markdown/documentation/condition.md +24 -0
  99. wbcore/contrib/workflow/static/workflow/markdown/documentation/decisionstep.md +30 -0
  100. wbcore/contrib/workflow/static/workflow/markdown/documentation/emailstep.md +45 -0
  101. wbcore/contrib/workflow/static/workflow/markdown/documentation/finishstep.md +33 -0
  102. wbcore/contrib/workflow/static/workflow/markdown/documentation/joinstep.md +33 -0
  103. wbcore/contrib/workflow/static/workflow/markdown/documentation/process.md +33 -0
  104. wbcore/contrib/workflow/static/workflow/markdown/documentation/processstep.md +51 -0
  105. wbcore/contrib/workflow/static/workflow/markdown/documentation/scriptstep.md +33 -0
  106. wbcore/contrib/workflow/static/workflow/markdown/documentation/splitstep.md +30 -0
  107. wbcore/contrib/workflow/static/workflow/markdown/documentation/startstep.md +27 -0
  108. wbcore/contrib/workflow/static/workflow/markdown/documentation/transition.md +27 -0
  109. wbcore/contrib/workflow/static/workflow/markdown/documentation/userstep.md +42 -0
  110. wbcore/contrib/workflow/static/workflow/markdown/documentation/workflow.md +32 -0
  111. wbcore/contrib/workflow/templates/Test_Templates.txt +25 -0
  112. wbcore/contrib/workflow/tests/test_models/step/test_decision_step.py +79 -0
  113. wbcore/contrib/workflow/tests/test_models/step/test_email_step.py +45 -0
  114. wbcore/contrib/workflow/tests/test_models/step/test_finish_step.py +105 -0
  115. wbcore/contrib/workflow/tests/test_models/step/test_join_step.py +127 -0
  116. wbcore/contrib/workflow/tests/test_models/step/test_script_step.py +24 -0
  117. wbcore/contrib/workflow/tests/test_models/step/test_split_step.py +49 -0
  118. wbcore/contrib/workflow/tests/test_models/step/test_step.py +621 -0
  119. wbcore/contrib/workflow/tests/test_models/step/test_user_step.py +225 -0
  120. wbcore/contrib/workflow/tests/test_models/test_condition.py +103 -0
  121. wbcore/contrib/workflow/tests/test_models/test_data.py +134 -0
  122. wbcore/contrib/workflow/tests/test_models/test_process.py +98 -0
  123. wbcore/contrib/workflow/tests/test_models/test_transition.py +128 -0
  124. wbcore/contrib/workflow/tests/test_models/test_workflow.py +358 -0
  125. wbcore/locale/de/LC_MESSAGES/django.po +667 -0
  126. wbcore/templates/errors/404.html +134 -0
  127. wbcore/templates/errors/500.html +138 -0
  128. wbcore/templates/errors/503.html +132 -0
  129. wbcore/templates/errors/custom.html +132 -0
  130. wbcore/templates/forms.py +0 -0
  131. wbcore/templates/notifications/email_template.html +43 -0
  132. wbcore/templates/wbcore/admin/change_list.html +8 -0
  133. wbcore/templates/wbcore/admin/csv_form.html +15 -0
  134. wbcore/templates/wbcore/dynamic_color_array.html +29 -0
  135. wbcore/templates/wbcore/email_base_template.html +335 -0
  136. wbcore/templates/wbcore/email_notification_template.html +10 -0
  137. wbcore/templates/wbcore/frontend.html +51 -0
  138. wbcore/test/e2e_helpers_methods/e2e_checks.py +121 -0
  139. wbcore/test/e2e_helpers_methods/e2e_helper_methods.py +395 -0
  140. wbcore/tests/test_permissions/test_backend.py +29 -0
  141. {wbcore-2.2.1.dist-info → wbcore-2.2.4.dist-info}/METADATA +1 -1
  142. {wbcore-2.2.1.dist-info → wbcore-2.2.4.dist-info}/RECORD +143 -3
  143. {wbcore-2.2.1.dist-info → wbcore-2.2.4.dist-info}/WHEEL +0 -0
@@ -0,0 +1,128 @@
1
+ from unittest.mock import patch
2
+
3
+ import pytest
4
+ from wbcore.contrib.workflow.factories import UserStepFactory
5
+ from wbcore.contrib.workflow.models import Condition
6
+
7
+
8
+ @pytest.mark.django_db
9
+ class TestTransition:
10
+ def test_all_conditions_satisfied_no_conditions(self, transition_factory, process_step_factory):
11
+ transition = transition_factory()
12
+ process_step = process_step_factory()
13
+ assert transition.all_conditions_satisfied(process_step)
14
+
15
+ @patch("wbcore.contrib.workflow.models.step.Step.set_failed")
16
+ @patch("wbcore.contrib.workflow.models.process.ProcessStep.get_instance")
17
+ def test_all_conditions_satisfied_no_instance(
18
+ self,
19
+ mock_get_instance,
20
+ mock_failed,
21
+ random_child_step_factory,
22
+ transition_factory,
23
+ condition_factory,
24
+ process_step_factory,
25
+ ):
26
+ transition = transition_factory()
27
+ condition_factory(transition=transition)
28
+ step = random_child_step_factory(exclude_factories=[UserStepFactory])
29
+ process_step = process_step_factory(step=step)
30
+ mock_get_instance.return_value = None
31
+ assert not transition.all_conditions_satisfied(process_step)
32
+ assert mock_failed.call_args.args[0] == process_step
33
+
34
+ @patch("wbcore.contrib.workflow.models.process.ProcessStep.get_instance")
35
+ @patch("wbcore.contrib.workflow.models.condition.Condition.satisfied")
36
+ def test_all_conditions_satisfied(
37
+ self, mock_satisfied, mock_get_instance, transition_factory, condition_factory, process_step_factory
38
+ ):
39
+ transition = transition_factory()
40
+ process_step = process_step_factory()
41
+ attached_instance = process_step.process.instance
42
+ condition_factory()
43
+ condition_factory(transition=transition)
44
+ condition_factory(transition=transition)
45
+ mock_get_instance.return_value = attached_instance
46
+ mock_satisfied.return_value = True
47
+ assert transition.all_conditions_satisfied(process_step)
48
+ assert mock_satisfied.call_args.args == (attached_instance,)
49
+ assert mock_satisfied.call_count == 2
50
+
51
+ @patch("wbcore.contrib.workflow.models.step.Step.set_failed")
52
+ @patch("wbcore.contrib.workflow.models.process.ProcessStep.get_instance")
53
+ def test_all_conditions_satisfied_errors(
54
+ self,
55
+ mock_get_instance,
56
+ mock_failed,
57
+ random_child_step_factory,
58
+ transition_factory,
59
+ condition_factory,
60
+ process_step_factory,
61
+ ):
62
+ transition = transition_factory()
63
+ step = random_child_step_factory(exclude_factories=[UserStepFactory])
64
+ process_step = process_step_factory(step=step)
65
+ attached_instance = process_step.process.instance
66
+ condition_factory()
67
+ condition_factory(
68
+ transition=transition,
69
+ operator=Condition.Operator.EQ,
70
+ expected_value=attached_instance.first_name,
71
+ negate_operator=False,
72
+ )
73
+ condition_factory(
74
+ transition=transition,
75
+ attribute_name="last_name",
76
+ operator=Condition.Operator.EQ,
77
+ expected_value=attached_instance.last_name,
78
+ negate_operator=False,
79
+ )
80
+ condition_factory(
81
+ transition=transition,
82
+ attribute_name="Test",
83
+ operator=Condition.Operator.EQ,
84
+ expected_value=attached_instance.first_name,
85
+ negate_operator=True,
86
+ )
87
+ mock_get_instance.return_value = attached_instance
88
+ assert not transition.all_conditions_satisfied(process_step)
89
+ assert mock_failed.call_args.args[0] == process_step
90
+
91
+ @patch("wbcore.contrib.workflow.models.step.Step.set_failed")
92
+ @patch("wbcore.contrib.workflow.models.process.ProcessStep.get_instance")
93
+ def test_all_conditions_satisfied_false(
94
+ self,
95
+ mock_get_instance,
96
+ mock_failed,
97
+ random_child_step_factory,
98
+ transition_factory,
99
+ condition_factory,
100
+ process_step_factory,
101
+ ):
102
+ transition = transition_factory()
103
+ step = random_child_step_factory(exclude_factories=[UserStepFactory])
104
+ process_step = process_step_factory(step=step)
105
+ attached_instance = process_step.process.instance
106
+ condition_factory()
107
+ condition_factory(
108
+ transition=transition,
109
+ operator=Condition.Operator.EQ,
110
+ expected_value=attached_instance.first_name,
111
+ negate_operator=False,
112
+ )
113
+ condition_factory(
114
+ transition=transition,
115
+ operator=Condition.Operator.EQ,
116
+ expected_value=attached_instance.first_name,
117
+ negate_operator=True,
118
+ )
119
+ condition_factory(
120
+ transition=transition,
121
+ attribute_name="last_name",
122
+ operator=Condition.Operator.EQ,
123
+ expected_value=attached_instance.last_name,
124
+ negate_operator=False,
125
+ )
126
+ mock_get_instance.return_value = attached_instance
127
+ assert not transition.all_conditions_satisfied(process_step)
128
+ assert not mock_failed.called
@@ -0,0 +1,358 @@
1
+ from unittest.mock import patch
2
+
3
+ import factory
4
+ import pytest
5
+ from django.contrib.contenttypes.models import ContentType
6
+ from wbcore.contrib.authentication.factories import GroupFactory, UserFactory
7
+ from wbcore.contrib.authentication.models import Permission
8
+ from wbcore.contrib.directory.factories import CompanyFactory, PersonFactory
9
+ from wbcore.contrib.directory.models import Person
10
+ from wbcore.contrib.workflow.models import (
11
+ Condition,
12
+ DataValue,
13
+ Process,
14
+ ProcessStep,
15
+ Transition,
16
+ Workflow,
17
+ )
18
+ from wbcore.contrib.workflow.models.workflow import re_render_workflow_graph
19
+ from wbcore.contrib.workflow.sites import workflow_site
20
+ from wbcore.test.utils import get_or_create_superuser
21
+
22
+
23
+ @pytest.mark.django_db
24
+ class TestWorkflow:
25
+ @patch("wbcore.contrib.workflow.models.workflow.transaction.on_commit")
26
+ def test_start_workflow_without_attached_instance(
27
+ self, mock_commit, workflow_factory, data_factory, start_step_factory
28
+ ):
29
+ workflow = workflow_factory(model=None, status_field=None, preserve_instance=False)
30
+ data1 = data_factory(workflow=workflow)
31
+ default_value = "Test"
32
+ data2 = data_factory(workflow=workflow, default=default_value)
33
+ start_step = start_step_factory(workflow=workflow)
34
+ workflow.start_workflow(start_step)
35
+ process_qs = Process.objects.filter(workflow=workflow, instance_id=None, content_type=None)
36
+ assert process_qs.exists()
37
+ assert DataValue.objects.filter(data=data1, process=process_qs.first()).exists()
38
+ assert DataValue.objects.filter(data=data2, process=process_qs.first(), value=default_value).exists()
39
+ assert mock_commit.called
40
+
41
+ @patch("wbcore.contrib.workflow.models.workflow.transaction.on_commit")
42
+ def test_start_workflow_with_attached_instance(
43
+ self, mock_commit, workflow_factory, start_step_factory, data_factory
44
+ ):
45
+ attached_person = PersonFactory()
46
+ workflow = workflow_factory(preserve_instance=True)
47
+ data1 = data_factory(workflow=workflow)
48
+ default_value = "Test"
49
+ data2 = data_factory(workflow=workflow, default=default_value)
50
+ start_step = start_step_factory()
51
+ workflow_site.registered_model_classes_serializer_map[
52
+ Person
53
+ ] = "wbcore.contrib.directory.serializers.PersonModelSerializer"
54
+ workflow.start_workflow(start_step, attached_person)
55
+ process_qs = Process.objects.filter(
56
+ workflow=workflow,
57
+ instance_id=attached_person.pk,
58
+ content_type=ContentType.objects.get_for_model(Person),
59
+ preserved_instance__isnull=False,
60
+ )
61
+ assert process_qs.exists()
62
+ assert DataValue.objects.filter(data=data1, process=process_qs.first()).exists()
63
+ assert DataValue.objects.filter(data=data2, process=process_qs.first(), value=default_value).exists()
64
+ assert mock_commit.called
65
+
66
+ def test_get_start_steps_for_workflow(self, workflow_factory, start_step_factory):
67
+ workflow = workflow_factory(model=None, single_instance_execution=False, status_field=None)
68
+ start_step = start_step_factory(workflow=workflow)
69
+ start_step_factory()
70
+ start_transitions = workflow.get_start_steps_for_workflow()
71
+ assert list(start_transitions) == [start_step]
72
+
73
+ def test_get_start_steps_for_workflow_single_instance_execution(
74
+ self, workflow_factory, process_factory, start_step_factory
75
+ ):
76
+ workflow = workflow_factory(model=None, single_instance_execution=True, status_field=None)
77
+ start_step_factory(workflow=workflow)
78
+ start_step_factory()
79
+ process_factory(state=Process.ProcessState.ACTIVE, workflow=workflow)
80
+ assert not workflow.get_start_steps_for_workflow().exists()
81
+
82
+ def test_get_start_steps_for_workflow_single_instance_execution_no_running_process(
83
+ self, workflow_factory, process_factory, start_step_factory
84
+ ):
85
+ workflow = workflow_factory(model=None, single_instance_execution=True, status_field=None)
86
+ start_step = start_step_factory(workflow=workflow)
87
+ start_step_factory()
88
+ process_factory(state=Process.ProcessState.FINISHED, workflow=workflow)
89
+ start_transitions = workflow.get_start_steps_for_workflow()
90
+ assert list(start_transitions) == [start_step]
91
+
92
+ def test_get_start_steps_for_workflow_with_attached_instance(self, workflow_factory, start_step_factory):
93
+ workflow = workflow_factory()
94
+ start_step_factory(workflow=workflow)
95
+ start_step_factory()
96
+ assert not workflow.get_start_steps_for_workflow().exists()
97
+
98
+ def test_get_start_steps_for_instance(self, workflow_factory, start_step_factory):
99
+ person = PersonFactory()
100
+ workflow = workflow_factory()
101
+ start_step = start_step_factory(workflow=workflow, status=person.first_name)
102
+ start_step_factory(workflow=workflow)
103
+ assert Workflow.get_start_steps_for_instance(person) == [start_step]
104
+
105
+ def test_get_start_steps_for_instance_no_model_attached(self, workflow_factory, start_step_factory):
106
+ person = PersonFactory()
107
+ workflow = workflow_factory(model=None, status_field=None)
108
+ start_step_factory(workflow=workflow, status=person.first_name)
109
+ assert not Workflow.get_start_steps_for_instance(person)
110
+
111
+ def test_get_start_steps_for_instance_wrong_instance(self, workflow_factory, start_step_factory):
112
+ company = CompanyFactory()
113
+ workflow = workflow_factory()
114
+ start_step_factory(workflow=workflow)
115
+ assert not Workflow.get_start_steps_for_instance(company)
116
+
117
+ def test_get_start_steps_for_instance_single_instance_execution(
118
+ self, workflow_factory, process_factory, start_step_factory
119
+ ):
120
+ person = PersonFactory()
121
+ workflow = workflow_factory(single_instance_execution=True)
122
+ start_step_factory(workflow=workflow, status=person.first_name)
123
+ process_factory(finished=None, workflow=workflow, instance=person)
124
+ assert not Workflow.get_start_steps_for_instance(person)
125
+
126
+ def test_get_start_steps_for_instance_single_instance_execution_no_running_process(
127
+ self, workflow_factory, process_factory, start_step_factory
128
+ ):
129
+ attached_instance = PersonFactory()
130
+ workflow = workflow_factory(single_instance_execution=True)
131
+ start_step = start_step_factory(workflow=workflow, status=attached_instance.first_name)
132
+ start_step_factory()
133
+ process_factory(workflow=workflow, instance=attached_instance)
134
+ wrong_instance = CompanyFactory()
135
+ process_factory(workflow=workflow, finished=None, instance=wrong_instance)
136
+ assert Workflow.get_start_steps_for_instance(attached_instance) == [start_step]
137
+
138
+ def test_get_start_steps_for_instance_wrong_status_field(self, workflow_factory, start_step_factory):
139
+ person = PersonFactory()
140
+ workflow = workflow_factory(status_field="Test")
141
+ start_step_factory(workflow=workflow, status=person.first_name)
142
+ assert not Workflow.get_start_steps_for_instance(person)
143
+
144
+ def test_get_start_steps_for_instance_wrong_status(self, workflow_factory, start_step_factory):
145
+ person = PersonFactory()
146
+ workflow = workflow_factory()
147
+ start_step_factory(workflow=workflow, status="Test")
148
+ assert not Workflow.get_start_steps_for_instance(person)
149
+
150
+ def test_get_next_user_step_transitions_for_instance_superuser(
151
+ self, workflow_factory, transition_factory, process_step_factory, user_step_factory
152
+ ):
153
+ workflow = workflow_factory()
154
+ step = user_step_factory(workflow=workflow, permission=Permission.objects.last())
155
+ transition = transition_factory(from_step=step, to_step__workflow=workflow)
156
+ process_step = process_step_factory(step=step, state=ProcessStep.StepState.ACTIVE)
157
+ attached_instance = process_step.process.instance
158
+ superuser = get_or_create_superuser()
159
+ start_transitions = Workflow.get_next_user_step_transitions_for_instance(attached_instance, superuser)
160
+ assert start_transitions[0][0] == [transition]
161
+ assert str(start_transitions[0][1].pk) == process_step.pk
162
+
163
+ def test_get_next_user_step_transitions_for_instance_wrong_instance(
164
+ self, workflow_factory, transition_factory, process_step_factory, user_step_factory
165
+ ):
166
+ workflow = workflow_factory()
167
+ instance = PersonFactory()
168
+ step = user_step_factory(workflow=workflow, permission=Permission.objects.last())
169
+ transition_factory(from_step=step, to_step__workflow=workflow)
170
+ process_step_factory(step=step, state=ProcessStep.StepState.ACTIVE)
171
+ superuser = get_or_create_superuser()
172
+ assert not Workflow.get_next_user_step_transitions_for_instance(instance, superuser)
173
+
174
+ def test_get_next_user_step_transitions_for_instance_user_is_assignee(
175
+ self, workflow_factory, transition_factory, process_step_factory, user_step_factory
176
+ ):
177
+ workflow = workflow_factory()
178
+ step = user_step_factory(workflow=workflow)
179
+ transition = transition_factory(from_step=step, to_step__workflow=workflow)
180
+ user = UserFactory()
181
+ process_step = process_step_factory(step=step, state=ProcessStep.StepState.ACTIVE, assignee=user)
182
+ attached_instance = process_step.process.instance
183
+ start_transitions = Workflow.get_next_user_step_transitions_for_instance(attached_instance, user)
184
+ assert start_transitions[0][0] == [transition]
185
+ assert str(start_transitions[0][1].pk) == process_step.pk
186
+
187
+ def test_get_next_user_step_transitions_for_instance_user_in_assignee_group(
188
+ self, workflow_factory, transition_factory, process_step_factory, user_step_factory
189
+ ):
190
+ workflow = workflow_factory()
191
+ step = user_step_factory(workflow=workflow, assignee_method=None)
192
+ transition = transition_factory(from_step=step, to_step__workflow=workflow)
193
+ group = GroupFactory()
194
+ user = UserFactory(groups=[group])
195
+ process_step = process_step_factory(step=step, state=ProcessStep.StepState.ACTIVE, group=group)
196
+ attached_instance = process_step.process.instance
197
+ start_transitions = Workflow.get_next_user_step_transitions_for_instance(attached_instance, user)
198
+ assert start_transitions[0][0] == [transition]
199
+ assert str(start_transitions[0][1].pk) == process_step.pk
200
+
201
+ def test_get_next_user_step_transitions_for_instance_user_in_assignee_group_but_with_method(
202
+ self, workflow_factory, transition_factory, process_step_factory, user_step_factory
203
+ ):
204
+ workflow = workflow_factory()
205
+ step = user_step_factory(workflow=workflow, permission=Permission.objects.last())
206
+ transition_factory(from_step=step, to_step__workflow=workflow)
207
+ group = GroupFactory()
208
+ user = UserFactory(groups=[group])
209
+ process_step = process_step_factory(step=step, state=ProcessStep.StepState.ACTIVE, group=group)
210
+ attached_instance = process_step.process.instance
211
+ assert not Workflow.get_next_user_step_transitions_for_instance(attached_instance, user)
212
+
213
+ def test_get_next_user_step_transitions_for_instance_user_has_permission(
214
+ self, workflow_factory, transition_factory, process_step_factory, user_step_factory
215
+ ):
216
+ workflow = workflow_factory()
217
+ step = user_step_factory(workflow=workflow, permission=Permission.objects.last())
218
+ transition = transition_factory(from_step=step, to_step__workflow=workflow)
219
+ user = UserFactory()
220
+ user.user_permissions.add(step.permission)
221
+ process_step = process_step_factory(step=step, state=ProcessStep.StepState.ACTIVE, assignee=user)
222
+ attached_instance = process_step.process.instance
223
+ start_transitions = Workflow.get_next_user_step_transitions_for_instance(attached_instance, user)
224
+ assert start_transitions[0][0] == [transition]
225
+ assert str(start_transitions[0][1].pk) == process_step.pk
226
+
227
+ def test_get_next_user_step_transitions_for_instance_user_has_group_permission(
228
+ self, workflow_factory, transition_factory, process_step_factory, user_step_factory
229
+ ):
230
+ workflow = workflow_factory()
231
+ step = user_step_factory(workflow=workflow, permission=Permission.objects.last())
232
+ transition = transition_factory(from_step=step, to_step__workflow=workflow)
233
+ group = GroupFactory(permissions=[step.permission])
234
+ user = UserFactory(groups=[group])
235
+ process_step = process_step_factory(step=step, state=ProcessStep.StepState.ACTIVE, assignee=user)
236
+ attached_instance = process_step.process.instance
237
+ start_transitions = Workflow.get_next_user_step_transitions_for_instance(attached_instance, user)
238
+ assert start_transitions[0][0] == [transition]
239
+ assert str(start_transitions[0][1].pk) == process_step.pk
240
+
241
+ def test_get_next_user_step_transitions_for_instance_user_has_no_permission(
242
+ self, workflow_factory, transition_factory, process_step_factory, user_step_factory
243
+ ):
244
+ workflow = workflow_factory()
245
+ step = user_step_factory(workflow=workflow, permission=Permission.objects.last())
246
+ transition_factory(from_step=step, to_step__workflow=workflow)
247
+ user = UserFactory()
248
+ process_step = process_step_factory(step=step, state=ProcessStep.StepState.ACTIVE, assignee=user)
249
+ attached_instance = process_step.process.instance
250
+ assert not Workflow.get_next_user_step_transitions_for_instance(attached_instance, user)
251
+
252
+ def test_get_next_user_step_transitions_for_instance_user_no_permission_selected(
253
+ self, workflow_factory, transition_factory, process_step_factory, user_step_factory
254
+ ):
255
+ workflow = workflow_factory()
256
+ step = user_step_factory(workflow=workflow)
257
+ transition = transition_factory(from_step=step, to_step__workflow=workflow)
258
+ user = UserFactory()
259
+ process_step = process_step_factory(step=step, state=ProcessStep.StepState.ACTIVE, assignee=user)
260
+ attached_instance = process_step.process.instance
261
+ start_transitions = Workflow.get_next_user_step_transitions_for_instance(attached_instance, user)
262
+ assert start_transitions[0][0] == [transition]
263
+ assert str(start_transitions[0][1].pk) == process_step.pk
264
+
265
+ def test_get_next_user_step_transitions_for_instance_condition_satisfied(
266
+ self, workflow_factory, transition_factory, process_step_factory, user_step_factory, condition_factory
267
+ ):
268
+ workflow = workflow_factory()
269
+ person = PersonFactory()
270
+ step = user_step_factory(workflow=workflow)
271
+ transition = transition_factory(from_step=step, to_step__workflow=workflow)
272
+ condition_factory(
273
+ transition=transition,
274
+ attribute_name="first_name",
275
+ expected_value=person.first_name,
276
+ operator=Condition.Operator.EQ,
277
+ negate_operator=False,
278
+ )
279
+ superuser = get_or_create_superuser()
280
+ process_step = process_step_factory(
281
+ step=step, state=ProcessStep.StepState.ACTIVE, assignee=superuser, process__instance=person
282
+ )
283
+ start_transitions = Workflow.get_next_user_step_transitions_for_instance(person, superuser)
284
+ assert start_transitions[0][0] == [transition]
285
+ assert str(start_transitions[0][1].pk) == process_step.pk
286
+
287
+ def test_get_next_user_step_transitions_for_instance_condition_not_satisfied(
288
+ self, workflow_factory, transition_factory, process_step_factory, user_step_factory, condition_factory
289
+ ):
290
+ workflow = workflow_factory()
291
+ person = PersonFactory()
292
+ step = user_step_factory(workflow=workflow)
293
+ transition = transition_factory(from_step=step, to_step__workflow=workflow)
294
+ condition_factory(
295
+ transition=transition,
296
+ attribute_name="first_name",
297
+ expected_value=person.first_name,
298
+ operator=Condition.Operator.EQ,
299
+ negate_operator=True,
300
+ )
301
+ superuser = get_or_create_superuser()
302
+ process_step_factory(
303
+ step=step, state=ProcessStep.StepState.ACTIVE, assignee=superuser, process__instance=person
304
+ )
305
+ assert not Workflow.get_next_user_step_transitions_for_instance(person, superuser)
306
+
307
+ @patch("wbcore.contrib.workflow.models.workflow.Workflow.generate_workflow_png")
308
+ def test_re_render_workflow_graph_workflow(self, mock_generate, workflow_factory):
309
+ workflow = workflow_factory()
310
+ old_graph = workflow.graph
311
+ new_graph = factory.django.ImageField()._make_data({"width": 1024, "height": 768})
312
+ mock_generate.return_value = new_graph
313
+ re_render_workflow_graph(sender=Workflow, instance=workflow, raw=False)
314
+ assert mock_generate.call_count == 1
315
+ assert workflow.graph != old_graph
316
+
317
+ @patch("wbcore.contrib.workflow.models.workflow.Workflow.generate_workflow_png")
318
+ def test_re_render_workflow_graph_step(self, mock_generate, random_child_step_factory):
319
+ step = random_child_step_factory()
320
+ old_graph = step.workflow.graph
321
+ new_graph = factory.django.ImageField()._make_data({"width": 1024, "height": 768})
322
+ mock_generate.return_value = new_graph
323
+ re_render_workflow_graph(sender=step.__class__, instance=step, raw=False)
324
+ # Not really sure why its called twice but as long as we have no infinite loop I'm fine
325
+ assert mock_generate.call_count == 2
326
+ assert step.workflow.graph != old_graph
327
+
328
+ @patch("wbcore.contrib.workflow.models.workflow.Workflow.generate_workflow_png")
329
+ def test_re_render_workflow_graph_transition(self, mock_generate, transition_factory):
330
+ transition = transition_factory()
331
+ old_graph = transition.to_step.workflow.graph
332
+ new_graph = factory.django.ImageField()._make_data({"width": 1024, "height": 768})
333
+ mock_generate.return_value = new_graph
334
+ re_render_workflow_graph(sender=Transition, instance=transition, raw=False)
335
+ # Not really sure why its called twice but as long as we have no infinite loop I'm fine
336
+ assert mock_generate.call_count == 2
337
+ assert transition.to_step.workflow.graph != old_graph
338
+
339
+ @patch("wbcore.contrib.workflow.models.workflow.Workflow.generate_workflow_png")
340
+ def test_re_render_workflow_graph_condition(self, mock_generate, condition_factory):
341
+ condition = condition_factory()
342
+ old_graph = condition.transition.to_step.workflow.graph
343
+ new_graph = factory.django.ImageField()._make_data({"width": 1024, "height": 768})
344
+ mock_generate.return_value = new_graph
345
+ re_render_workflow_graph(sender=Condition, instance=condition, raw=False)
346
+ # Not really sure why its called twice but as long as we have no infinite loop I'm fine
347
+ assert mock_generate.call_count == 2
348
+ assert condition.transition.to_step.workflow.graph != old_graph
349
+
350
+ @patch("wbcore.contrib.workflow.models.workflow.Workflow.generate_workflow_png")
351
+ def test_re_render_workflow_graph_sender_renamed(self, mock_generate, workflow_factory):
352
+ workflow = workflow_factory()
353
+ old_graph = workflow.graph
354
+ new_graph = factory.django.ImageField()._make_data({"width": 1024, "height": 768})
355
+ mock_generate.return_value = new_graph
356
+ re_render_workflow_graph(sender=ProcessStep, instance=workflow, raw=False)
357
+ assert mock_generate.call_count == 0
358
+ assert workflow.graph == old_graph