wbcrm 2.2.1__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 wbcrm might be problematic. Click here for more details.

Files changed (155) hide show
  1. wbcrm/__init__.py +1 -0
  2. wbcrm/admin/__init__.py +4 -0
  3. wbcrm/admin/accounts.py +59 -0
  4. wbcrm/admin/activities.py +101 -0
  5. wbcrm/admin/groups.py +7 -0
  6. wbcrm/admin/products.py +8 -0
  7. wbcrm/apps.py +5 -0
  8. wbcrm/configurations/__init__.py +1 -0
  9. wbcrm/configurations/base.py +16 -0
  10. wbcrm/dynamic_preferences_registry.py +38 -0
  11. wbcrm/factories/__init__.py +14 -0
  12. wbcrm/factories/accounts.py +56 -0
  13. wbcrm/factories/activities.py +125 -0
  14. wbcrm/factories/groups.py +23 -0
  15. wbcrm/factories/products.py +10 -0
  16. wbcrm/filters/__init__.py +10 -0
  17. wbcrm/filters/accounts.py +67 -0
  18. wbcrm/filters/activities.py +181 -0
  19. wbcrm/filters/groups.py +20 -0
  20. wbcrm/filters/products.py +37 -0
  21. wbcrm/filters/signals.py +94 -0
  22. wbcrm/migrations/0001_initial_squashed_squashed_0032_productcompanyrelationship_alter_product_prospects_and_more.py +3948 -0
  23. wbcrm/migrations/0002_alter_activity_repeat_choice.py +32 -0
  24. wbcrm/migrations/0003_remove_activity_external_id_and_more.py +63 -0
  25. wbcrm/migrations/0004_alter_activity_status.py +28 -0
  26. wbcrm/migrations/0005_account_accountrole_accountroletype_and_more.py +182 -0
  27. wbcrm/migrations/0006_alter_activity_location.py +17 -0
  28. wbcrm/migrations/0007_alter_account_status.py +23 -0
  29. wbcrm/migrations/0008_alter_activity_options.py +16 -0
  30. wbcrm/migrations/0009_alter_account_is_public.py +19 -0
  31. wbcrm/migrations/0010_alter_account_reference_id.py +17 -0
  32. wbcrm/migrations/0011_activity_summary.py +22 -0
  33. wbcrm/migrations/0012_alter_activity_summary.py +17 -0
  34. wbcrm/migrations/0013_account_action_plan_account_relationship_status_and_more.py +34 -0
  35. wbcrm/migrations/0014_alter_account_relationship_status.py +24 -0
  36. wbcrm/migrations/0015_alter_activity_type.py +23 -0
  37. wbcrm/migrations/0016_auto_20241205_1015.py +106 -0
  38. wbcrm/migrations/__init__.py +0 -0
  39. wbcrm/models/__init__.py +4 -0
  40. wbcrm/models/accounts.py +637 -0
  41. wbcrm/models/activities.py +1335 -0
  42. wbcrm/models/groups.py +118 -0
  43. wbcrm/models/products.py +83 -0
  44. wbcrm/models/recurrence.py +279 -0
  45. wbcrm/preferences.py +14 -0
  46. wbcrm/serializers/__init__.py +23 -0
  47. wbcrm/serializers/accounts.py +126 -0
  48. wbcrm/serializers/activities.py +526 -0
  49. wbcrm/serializers/groups.py +30 -0
  50. wbcrm/serializers/products.py +57 -0
  51. wbcrm/serializers/recurrence.py +90 -0
  52. wbcrm/serializers/signals.py +70 -0
  53. wbcrm/synchronization/__init__.py +0 -0
  54. wbcrm/synchronization/activity/__init__.py +0 -0
  55. wbcrm/synchronization/activity/admin.py +72 -0
  56. wbcrm/synchronization/activity/backend.py +207 -0
  57. wbcrm/synchronization/activity/backends/__init__.py +0 -0
  58. wbcrm/synchronization/activity/backends/google/__init__.py +2 -0
  59. wbcrm/synchronization/activity/backends/google/google_calendar_backend.py +399 -0
  60. wbcrm/synchronization/activity/backends/google/request_utils/__init__.py +16 -0
  61. wbcrm/synchronization/activity/backends/google/tasks.py +21 -0
  62. wbcrm/synchronization/activity/backends/google/tests/__init__.py +0 -0
  63. wbcrm/synchronization/activity/backends/google/tests/conftest.py +1 -0
  64. wbcrm/synchronization/activity/backends/google/tests/test_data.py +81 -0
  65. wbcrm/synchronization/activity/backends/google/tests/test_google_backend.py +319 -0
  66. wbcrm/synchronization/activity/backends/google/tests/test_utils.py +274 -0
  67. wbcrm/synchronization/activity/backends/google/typing_informations.py +139 -0
  68. wbcrm/synchronization/activity/backends/google/utils.py +216 -0
  69. wbcrm/synchronization/activity/backends/outlook/__init__.py +0 -0
  70. wbcrm/synchronization/activity/backends/outlook/backend.py +576 -0
  71. wbcrm/synchronization/activity/backends/outlook/msgraph.py +438 -0
  72. wbcrm/synchronization/activity/backends/outlook/parser.py +423 -0
  73. wbcrm/synchronization/activity/backends/outlook/tests/__init__.py +0 -0
  74. wbcrm/synchronization/activity/backends/outlook/tests/conftest.py +1 -0
  75. wbcrm/synchronization/activity/backends/outlook/tests/fixtures.py +606 -0
  76. wbcrm/synchronization/activity/backends/outlook/tests/test_admin.py +117 -0
  77. wbcrm/synchronization/activity/backends/outlook/tests/test_backend.py +269 -0
  78. wbcrm/synchronization/activity/backends/outlook/tests/test_controller.py +237 -0
  79. wbcrm/synchronization/activity/backends/outlook/tests/test_parser.py +173 -0
  80. wbcrm/synchronization/activity/controller.py +545 -0
  81. wbcrm/synchronization/activity/dynamic_preferences_registry.py +107 -0
  82. wbcrm/synchronization/activity/preferences.py +21 -0
  83. wbcrm/synchronization/activity/shortcuts.py +9 -0
  84. wbcrm/synchronization/activity/signals.py +28 -0
  85. wbcrm/synchronization/activity/tasks.py +21 -0
  86. wbcrm/synchronization/activity/urls.py +6 -0
  87. wbcrm/synchronization/activity/utils.py +46 -0
  88. wbcrm/synchronization/activity/views.py +37 -0
  89. wbcrm/synchronization/admin.py +1 -0
  90. wbcrm/synchronization/apps.py +15 -0
  91. wbcrm/synchronization/dynamic_preferences_registry.py +1 -0
  92. wbcrm/synchronization/management.py +36 -0
  93. wbcrm/synchronization/tasks.py +1 -0
  94. wbcrm/synchronization/urls.py +5 -0
  95. wbcrm/tasks.py +312 -0
  96. wbcrm/tests/__init__.py +0 -0
  97. wbcrm/tests/accounts/__init__.py +0 -0
  98. wbcrm/tests/accounts/test_models.py +380 -0
  99. wbcrm/tests/accounts/test_viewsets.py +87 -0
  100. wbcrm/tests/conftest.py +76 -0
  101. wbcrm/tests/disable_signals.py +52 -0
  102. wbcrm/tests/e2e/__init__.py +1 -0
  103. wbcrm/tests/e2e/e2e_wbcrm_utility.py +82 -0
  104. wbcrm/tests/e2e/test_e2e.py +369 -0
  105. wbcrm/tests/test_assignee_methods.py +39 -0
  106. wbcrm/tests/test_chartviewsets.py +111 -0
  107. wbcrm/tests/test_dto.py +63 -0
  108. wbcrm/tests/test_filters.py +51 -0
  109. wbcrm/tests/test_models.py +216 -0
  110. wbcrm/tests/test_recurrence.py +291 -0
  111. wbcrm/tests/test_report.py +20 -0
  112. wbcrm/tests/test_serializers.py +170 -0
  113. wbcrm/tests/test_tasks.py +94 -0
  114. wbcrm/tests/test_viewsets.py +967 -0
  115. wbcrm/tests/tests.py +120 -0
  116. wbcrm/typings.py +107 -0
  117. wbcrm/urls.py +67 -0
  118. wbcrm/viewsets/__init__.py +22 -0
  119. wbcrm/viewsets/accounts.py +121 -0
  120. wbcrm/viewsets/activities.py +315 -0
  121. wbcrm/viewsets/buttons/__init__.py +7 -0
  122. wbcrm/viewsets/buttons/accounts.py +27 -0
  123. wbcrm/viewsets/buttons/activities.py +68 -0
  124. wbcrm/viewsets/buttons/signals.py +17 -0
  125. wbcrm/viewsets/display/__init__.py +12 -0
  126. wbcrm/viewsets/display/accounts.py +110 -0
  127. wbcrm/viewsets/display/activities.py +443 -0
  128. wbcrm/viewsets/display/groups.py +22 -0
  129. wbcrm/viewsets/display/products.py +105 -0
  130. wbcrm/viewsets/endpoints/__init__.py +8 -0
  131. wbcrm/viewsets/endpoints/accounts.py +32 -0
  132. wbcrm/viewsets/endpoints/activities.py +30 -0
  133. wbcrm/viewsets/endpoints/groups.py +7 -0
  134. wbcrm/viewsets/endpoints/products.py +9 -0
  135. wbcrm/viewsets/groups.py +37 -0
  136. wbcrm/viewsets/menu/__init__.py +8 -0
  137. wbcrm/viewsets/menu/accounts.py +18 -0
  138. wbcrm/viewsets/menu/activities.py +61 -0
  139. wbcrm/viewsets/menu/groups.py +16 -0
  140. wbcrm/viewsets/menu/products.py +20 -0
  141. wbcrm/viewsets/mixins.py +34 -0
  142. wbcrm/viewsets/previews/__init__.py +1 -0
  143. wbcrm/viewsets/previews/activities.py +10 -0
  144. wbcrm/viewsets/products.py +56 -0
  145. wbcrm/viewsets/recurrence.py +26 -0
  146. wbcrm/viewsets/titles/__init__.py +13 -0
  147. wbcrm/viewsets/titles/accounts.py +22 -0
  148. wbcrm/viewsets/titles/activities.py +61 -0
  149. wbcrm/viewsets/titles/products.py +13 -0
  150. wbcrm/viewsets/titles/utils.py +46 -0
  151. wbcrm/workflows/__init__.py +1 -0
  152. wbcrm/workflows/assignee_methods.py +25 -0
  153. wbcrm-2.2.1.dist-info/METADATA +11 -0
  154. wbcrm-2.2.1.dist-info/RECORD +155 -0
  155. wbcrm-2.2.1.dist-info/WHEEL +5 -0
@@ -0,0 +1,967 @@
1
+ import pytest
2
+ from django.contrib.messages import get_messages
3
+ from django.test import Client
4
+ from dynamic_preferences.registries import global_preferences_registry
5
+ from rest_framework import status
6
+ from rest_framework.reverse import reverse
7
+ from rest_framework.test import APIClient, APIRequestFactory
8
+ from wbcore.contrib.agenda.models import CalendarItem
9
+ from wbcore.contrib.authentication.factories import (
10
+ InternalUserFactory,
11
+ SuperUserFactory,
12
+ )
13
+ from wbcore.contrib.authentication.models import Permission
14
+ from wbcore.messages import InMemoryMessageStorage
15
+ from wbcore.test.utils import get_data_from_factory, get_kwargs, get_model_factory
16
+ from wbcrm.models import Activity, ActivityParticipant
17
+ from wbcrm.viewsets import (
18
+ ActivityParticipantModelViewSet,
19
+ ActivityTypeModelViewSet,
20
+ ActivityViewSet,
21
+ ProductModelViewSet,
22
+ )
23
+
24
+ # =====================================================================================================================
25
+ # TESTING ACTIVITY VIEWSETS
26
+ # =====================================================================================================================
27
+
28
+
29
+ @pytest.mark.django_db
30
+ class TestActivityModelViewSet:
31
+ api_factory = APIRequestFactory()
32
+
33
+ @pytest.mark.parametrize("mvs", [ActivityViewSet])
34
+ def test_random_cannot_see_private_item(self, mvs, activity_factory, user_factory):
35
+ user = user_factory(is_active=True, is_superuser=True)
36
+ item = activity_factory(visibility=CalendarItem.Visibility.PRIVATE, preceded_by=None)
37
+ request = self.api_factory.get("")
38
+ request.user = user
39
+ view = mvs.as_view({"get": "list"})
40
+ response = view(request).render()
41
+
42
+ assert response.status_code == status.HTTP_200_OK
43
+ assert response.data["results"]
44
+ assert len(response.data["results"]) == 1
45
+ assert response.data["results"][0]["id"] == item.id
46
+ assert response.data["results"][0]["title"] == "Private Activity"
47
+
48
+ # =================================================================================================================
49
+ # TESTING CONFIDENTIAL CALENDAR ITEMS
50
+ # =================================================================================================================
51
+
52
+ @pytest.mark.parametrize("mvs", [ActivityViewSet])
53
+ def test_manager_can_see_confidential_item(self, mvs, activity_factory, user_factory):
54
+ user = user_factory(is_active=True, is_superuser=True)
55
+ permission = Permission.objects.get(codename="administrate_confidential_items")
56
+ user.user_permissions.add(permission)
57
+ item = activity_factory(visibility=CalendarItem.Visibility.CONFIDENTIAL, preceded_by=None)
58
+ request = self.api_factory.get("")
59
+ request.user = user
60
+ view = mvs.as_view({"get": "list"})
61
+ response = view(request).render()
62
+
63
+ assert response.status_code == status.HTTP_200_OK
64
+ assert response.data["results"]
65
+ assert len(response.data["results"]) == 1
66
+ assert response.data["results"][0]["id"] == item.id
67
+ assert response.data["results"][0]["title"] == item.title
68
+
69
+ @pytest.mark.parametrize("mvs", [ActivityParticipantModelViewSet])
70
+ def test_create_activity_participant(self, mvs, activity_participant_factory):
71
+ # Arrange
72
+ activity_participant = activity_participant_factory()
73
+ superuser = InternalUserFactory(is_active=True, is_superuser=True)
74
+ data = get_data_from_factory(activity_participant, mvs, delete=True, superuser=superuser)
75
+ request = self.api_factory.post("", data=data)
76
+ request.user = superuser
77
+ kwargs = {"activity_id": activity_participant.activity.id}
78
+ view = mvs.as_view({"post": "create"})
79
+ # Act
80
+ response = view(request, **kwargs)
81
+ # Assert
82
+ assert response.status_code == status.HTTP_201_CREATED
83
+ assert response.data.get("instance")
84
+ assert response.data["instance"]["participant"] == activity_participant.participant.id
85
+ assert (
86
+ response.data["instance"]["participation_status"]
87
+ == activity_participant.participation_status
88
+ == ActivityParticipant.ParticipationStatus.NOTRESPONDED
89
+ )
90
+ assert response.data["instance"]["activity"] == activity_participant.activity.id
91
+
92
+ # @pytest.mark.parametrize("mvs", [ActivityParticipantModelViewSet])
93
+ def test_get_activity_participant_instance(self, activity_participant_factory):
94
+ # Arranged
95
+ activity_participant = activity_participant_factory.create()
96
+ user = InternalUserFactory(is_active=True, is_superuser=True)
97
+ client = APIClient()
98
+ url = reverse(
99
+ "wbcrm:activity-participant-detail",
100
+ kwargs={"pk": activity_participant.id, "activity_id": activity_participant.activity.id},
101
+ )
102
+ client.force_authenticate(user)
103
+ response = client.get(url)
104
+
105
+ # Assert
106
+ assert response.status_code == status.HTTP_200_OK
107
+ assert response.data.get("instance")
108
+ assert not response.data.get("results")
109
+ assert response.data["instance"]["id"] == activity_participant.id
110
+
111
+ @pytest.mark.parametrize("mvs", [ActivityParticipantModelViewSet])
112
+ def test_get_activity_participant_list(self, mvs, activity_participant_factory):
113
+ # Arrange
114
+ activity_participant_1 = activity_participant_factory()
115
+ activity_participant_factory(activity=activity_participant_1.activity)
116
+ activity_participant_factory(activity=activity_participant_1.activity)
117
+ request = self.api_factory.get("")
118
+ request.user = InternalUserFactory(is_active=True, is_superuser=True)
119
+ view = mvs.as_view({"get": "list"})
120
+ kwargs = {"activity_id": activity_participant_1.activity.id}
121
+ # Act
122
+ response = view(request, **kwargs)
123
+ # Assert
124
+ assert response.status_code == status.HTTP_200_OK
125
+ assert not response.data.get("instance")
126
+ assert response.data.get("results")
127
+ assert response.data["results"]
128
+ assert len(response.data["results"]) == 3
129
+
130
+ @pytest.mark.parametrize("mvs", [ActivityParticipantModelViewSet])
131
+ def test_delete_activity_participant_instance(self, mvs, activity_participant_factory):
132
+ # Arrange
133
+ activity_participant = activity_participant_factory()
134
+ request = self.api_factory.delete("")
135
+ request.user = InternalUserFactory(is_active=True, is_superuser=True)
136
+ view = mvs.as_view({"delete": "destroy"})
137
+ kwargs = {"activity_id": activity_participant.activity.id}
138
+ # Act
139
+ response = view(request, pk=activity_participant.id, **kwargs)
140
+ # Assert
141
+ assert response.status_code == status.HTTP_204_NO_CONTENT
142
+
143
+ @pytest.mark.parametrize("mvs", [ActivityParticipantModelViewSet])
144
+ def test_partial_update_activity_participant_instance(self, mvs, activity_participant_factory, person_factory):
145
+ # Arrange
146
+ activity_participant = activity_participant_factory()
147
+ new_participant = person_factory()
148
+ superuser = InternalUserFactory(is_active=True, is_superuser=True)
149
+ request = self.api_factory.patch("", data={"participant": new_participant.id})
150
+ request.user = superuser
151
+ view = mvs.as_view({"patch": "partial_update"})
152
+ kwargs = {"activity_id": activity_participant.activity.id}
153
+ # Act
154
+ response = view(request, pk=activity_participant.id, **kwargs)
155
+ # Assert
156
+ assert response.status_code == status.HTTP_200_OK
157
+ assert response.data["instance"]["participant"] == new_participant.id
158
+ assert not response.data["instance"]["participant"] == activity_participant.participant.id
159
+
160
+ @pytest.mark.parametrize("mvs", [ActivityViewSet])
161
+ def test_msg_missing_company(
162
+ self,
163
+ mvs,
164
+ activity_factory,
165
+ person_factory,
166
+ company_factory,
167
+ ):
168
+ company_a = company_factory()
169
+ company_b = company_factory()
170
+ person = person_factory()
171
+ person.employers.set([company_a, company_b])
172
+ activity = activity_factory(participants=[person], companies=None, disable_participant_check=False)
173
+ request = APIRequestFactory().get("")
174
+ request.user = InternalUserFactory(is_active=True, is_superuser=True)
175
+ request.query_params = {}
176
+ request._messages = InMemoryMessageStorage(request)
177
+ mvs.request = request
178
+ mvs.kwargs = get_kwargs(activity, ActivityViewSet, request)
179
+ mvs.kwargs["pk"] = activity.pk
180
+ mvs().add_messages(request, instance=activity)
181
+ assert len(get_messages(request)._messages) > 0
182
+
183
+ @pytest.mark.parametrize("mvs", [ActivityViewSet])
184
+ def test_msg_missing_participant(
185
+ self,
186
+ mvs,
187
+ activity_factory,
188
+ person_factory,
189
+ company_factory,
190
+ ):
191
+ company = company_factory()
192
+ person = person_factory()
193
+ person.employers.set([company])
194
+ company.employees.set([person])
195
+ activity = activity_factory(participants=None, companies=[company], disable_participant_check=False)
196
+ activity.disable_participant_check = False
197
+ activity.save()
198
+ request = APIRequestFactory().put("")
199
+ request.user = InternalUserFactory(is_active=True, is_superuser=True)
200
+ request.query_params = {}
201
+ request._messages = InMemoryMessageStorage(request)
202
+ mvs.request = request
203
+ mvs.kwargs = get_kwargs(activity, ActivityViewSet, request)
204
+ mvs.kwargs["pk"] = activity.pk
205
+ mvs().add_messages(request, instance=activity)
206
+ assert len(get_messages(request)._messages) > 0
207
+
208
+ @pytest.mark.parametrize("mvs", [ActivityViewSet])
209
+ def test_msg_missing_participant_no_check(
210
+ self,
211
+ mvs,
212
+ activity_factory,
213
+ person_factory,
214
+ company_factory,
215
+ ):
216
+ company = company_factory()
217
+ person = person_factory()
218
+ person.employers.set([company])
219
+ company.employees.set([person])
220
+ internal_user = InternalUserFactory.create()
221
+ activity = activity_factory(
222
+ participants=None, creator=internal_user.profile, companies=[company], disable_participant_check=True
223
+ )
224
+ request = APIRequestFactory().put("")
225
+ request.user = internal_user
226
+ request.query_params = {}
227
+ request._messages = InMemoryMessageStorage(request)
228
+ mvs.request = request
229
+ mvs.kwargs = get_kwargs(activity, ActivityViewSet, request)
230
+ mvs.kwargs["pk"] = activity.pk
231
+ mvs().add_messages(request, instance=activity)
232
+ assert len(get_messages(request)._messages) == 0
233
+
234
+ @pytest.mark.parametrize("mvs", [ActivityViewSet])
235
+ def test_msg_missing_participant_and_company(
236
+ self,
237
+ mvs,
238
+ activity_factory,
239
+ person_factory,
240
+ company_factory,
241
+ ):
242
+ company_a = company_factory()
243
+ company_b = company_factory()
244
+ company_c = company_factory()
245
+ person_a = person_factory()
246
+ person_b = person_factory()
247
+ person_a.employers.set([company_a])
248
+ person_b.employers.set([company_b, company_c])
249
+ company_a.employees.set([person_a])
250
+ company_b.employees.set([person_b])
251
+ activity = activity_factory(participants=[person_b], companies=[company_a], disable_participant_check=False)
252
+ request = APIRequestFactory().patch("")
253
+ request.user = InternalUserFactory(is_active=True, is_superuser=True)
254
+ request.query_params = {}
255
+ request._messages = InMemoryMessageStorage(request)
256
+ mvs.request = request
257
+ mvs.kwargs = get_kwargs(activity, ActivityViewSet, request)
258
+ mvs.kwargs["pk"] = activity.pk
259
+ mvs().add_messages(request, instance=activity)
260
+ assert len(get_messages(request)._messages) > 0
261
+
262
+ @pytest.mark.parametrize("mvs", [ActivityViewSet])
263
+ def test_get_messages(self, mvs, activity_factory, recurring_activity_factory, person_factory):
264
+ request = APIRequestFactory().get("")
265
+ request.user = InternalUserFactory(is_active=True, is_superuser=True)
266
+ person1 = person_factory()
267
+ obj = recurring_activity_factory(
268
+ status=Activity.Status.PLANNED, repeat_choice=Activity.ReoccuranceChoice.DAILY, participants=(person1,)
269
+ )
270
+ activity_factory(start=obj.start, end=obj.end, participants=(person1,))
271
+ request.query_params = {}
272
+ request._messages = InMemoryMessageStorage(request)
273
+ mvs.request = request
274
+ mvs.kwargs = get_kwargs(obj, ActivityViewSet, request)
275
+ mvs.kwargs["pk"] = obj.pk
276
+ mvs().add_messages(request, instance=obj)
277
+ assert len(get_messages(request)._messages) > 0
278
+
279
+ @pytest.mark.parametrize("mvs", [ActivityViewSet])
280
+ def test_create_activity(self, mvs, activity_factory):
281
+ # Arrange
282
+ activity = activity_factory()
283
+ user = InternalUserFactory(is_active=True, is_superuser=True)
284
+ data = get_data_from_factory(activity, mvs, delete=True, superuser=user)
285
+ request = self.api_factory.post("", data=data)
286
+ request.user = user
287
+ kwargs = {}
288
+ view = mvs.as_view({"post": "create"})
289
+ # Act
290
+ response = view(request, kwargs).render()
291
+ # Assert
292
+ assert response.status_code == status.HTTP_201_CREATED
293
+ assert response.data.get("instance")
294
+ assert response.data["instance"]["title"] == activity.title
295
+
296
+ @pytest.mark.parametrize("mvs", [ActivityViewSet])
297
+ def test_create_reviewed_activity(self, mvs, activity_factory):
298
+ # Arrange
299
+ activity = activity_factory(result="A Test Review For This Activity!")
300
+ user = SuperUserFactory()
301
+ data = get_data_from_factory(activity, mvs, delete=True, superuser=user)
302
+ request = self.api_factory.post("", data=data)
303
+ request.user = user
304
+ kwargs = {}
305
+ view = mvs.as_view({"post": "create"})
306
+ # Act
307
+ response = view(request, kwargs).render()
308
+ # Assert
309
+ assert response.status_code == status.HTTP_201_CREATED
310
+ assert response.data.get("instance")
311
+ assert response.data["instance"]["title"] == activity.title
312
+ assert response.data["instance"]["result"] == activity.result
313
+
314
+ @pytest.mark.parametrize("mvs", [ActivityViewSet])
315
+ def test_get_activity_instance(self, mvs, activity_factory):
316
+ # Arrange
317
+ activity = activity_factory()
318
+ request = self.api_factory.get("")
319
+ request.user = InternalUserFactory(is_active=True, is_superuser=True)
320
+ view = mvs.as_view({"get": "retrieve"})
321
+ # Act
322
+ response = view(request, pk=activity.id).render()
323
+ # Assert
324
+ assert response.status_code == status.HTTP_200_OK
325
+ assert response.data.get("instance")
326
+ assert not response.data.get("results")
327
+ assert response.data["instance"]["id"] == activity.id
328
+
329
+ @pytest.mark.parametrize("mvs", [ActivityViewSet])
330
+ def test_get_activity_list(self, mvs, activity_factory):
331
+ # Arrange
332
+ activity_factory.create_batch(3, preceded_by=None)
333
+ request = self.api_factory.get("")
334
+ request.user = InternalUserFactory(is_active=True, is_superuser=True)
335
+ view = mvs.as_view({"get": "list"})
336
+ # Act
337
+ response = view(request).render()
338
+ # Assert
339
+ assert response.status_code == status.HTTP_200_OK
340
+ assert not response.data.get("instance")
341
+ assert response.data.get("results")
342
+ assert response.data["results"]
343
+ assert len(response.data["results"]) == 3
344
+
345
+ @pytest.mark.parametrize("mvs", [ActivityViewSet])
346
+ def test_delete_activity_instance(self, mvs, activity_factory):
347
+ # Arrange
348
+ activity = activity_factory()
349
+ request = self.api_factory.delete("")
350
+ request.user = InternalUserFactory(is_active=True, is_superuser=True)
351
+ view = mvs.as_view({"delete": "destroy"})
352
+ # Act
353
+ response = view(request, pk=activity.id).render()
354
+ # Assert
355
+ assert response.status_code == status.HTTP_204_NO_CONTENT
356
+
357
+ @pytest.mark.parametrize("mvs", [ActivityViewSet])
358
+ def test_update_activity_instance(self, mvs, activity_factory):
359
+ activity_old = activity_factory()
360
+ activity_new = activity_factory()
361
+ user = InternalUserFactory(is_active=True, is_superuser=True)
362
+ data = get_data_from_factory(activity_new, mvs, update=True, superuser=user)
363
+ request = self.api_factory.put("", data=data)
364
+ request.user = user
365
+ view = mvs.as_view({"put": "update"})
366
+ response = view(request, pk=activity_old.id).render()
367
+ assert response.status_code == status.HTTP_200_OK
368
+ assert not activity_old.title == activity_new.title
369
+ assert response.data["instance"]["id"] == activity_old.id
370
+
371
+ @pytest.mark.parametrize("mvs", [ActivityViewSet])
372
+ def test_update_reviewed_activity_instance(self, mvs, activity_factory):
373
+ user = SuperUserFactory()
374
+ client = Client()
375
+ client.force_login(user)
376
+ activity: Activity = activity_factory()
377
+ updated_result = activity.result + "Foo Bar"
378
+ data = get_data_from_factory(activity, mvs, update=True, superuser=user)
379
+ data["result"] = updated_result
380
+ assert activity.result != updated_result
381
+ update_url: str = reverse("wbcrm:activity-detail", args=[activity.pk])
382
+ response = client.put(update_url, data, content_type="application/json")
383
+ assert response.status_code == status.HTTP_200_OK
384
+ activity.refresh_from_db()
385
+ assert activity.result == updated_result
386
+
387
+ @pytest.mark.parametrize("mvs", [ActivityViewSet])
388
+ def test_partial_update_activity_instance(self, mvs, activity_factory):
389
+ activity = activity_factory()
390
+ activity.title
391
+ user = InternalUserFactory(is_active=True, is_superuser=True)
392
+ request = self.api_factory.patch("", data={"title": "New Title"})
393
+ request.user = user
394
+ view = mvs.as_view({"patch": "partial_update"})
395
+ response = view(request, pk=activity.id).render()
396
+ assert response.status_code == status.HTTP_200_OK
397
+ assert response.data["instance"]["id"] == activity.id
398
+
399
+ @pytest.mark.parametrize("mvs", [ActivityViewSet])
400
+ def test_partial_update_reviewed_activity_instance(self, mvs, activity_factory):
401
+ user = SuperUserFactory()
402
+ client = Client()
403
+ client.force_login(user)
404
+ activity: Activity = activity_factory()
405
+ updated_result = activity.result + "Foo Bar"
406
+ update_url: str = reverse("wbcrm:activity-detail", args=[activity.pk])
407
+
408
+ assert activity.result != updated_result
409
+ response = client.patch(update_url, {"result": updated_result}, content_type="application/json")
410
+ assert response.status_code == status.HTTP_200_OK
411
+ activity.refresh_from_db()
412
+ assert activity.result == updated_result
413
+
414
+ @pytest.mark.parametrize("mvs", [ActivityViewSet])
415
+ def test_conference_room_capacity_error_message(
416
+ self, mvs, activity_factory, person_factory, conference_room_factory
417
+ ):
418
+ room = conference_room_factory(capacity=2)
419
+ p1 = person_factory()
420
+ p2 = person_factory()
421
+ p3 = person_factory()
422
+ activity = activity_factory(conference_room=room, participants=[p1, p2, p3])
423
+ request = self.api_factory.get("")
424
+ request._messages = InMemoryMessageStorage(request)
425
+ request.user = InternalUserFactory(is_active=True, is_superuser=True)
426
+ view = mvs.as_view({"get": "retrieve"})
427
+ # Act
428
+ response = view(request, pk=activity.id).render()
429
+ assert len(response.data["messages"]) == 1
430
+
431
+ @pytest.mark.parametrize("mvs", [ActivityViewSet])
432
+ def test_conference_room_capacity_no_error_message(
433
+ self, mvs, activity_factory, person_factory, conference_room_factory
434
+ ):
435
+ room = conference_room_factory(capacity=3)
436
+ p1 = person_factory()
437
+ p2 = person_factory()
438
+ p3 = person_factory()
439
+ activity = activity_factory(conference_room=room, participants=[p1, p2, p3])
440
+ request = self.api_factory.get("")
441
+ request._messages = InMemoryMessageStorage(request)
442
+ request.user = InternalUserFactory(is_active=True, is_superuser=True)
443
+ view = mvs.as_view({"get": "retrieve"})
444
+ response = view(request, pk=activity.id).render()
445
+ assert len(response.data["messages"]) == 0
446
+
447
+ # =================================================================================================================
448
+ # TESTING PRIVATE ACTIVITIES
449
+ # =================================================================================================================
450
+
451
+ @pytest.mark.parametrize("mvs", [ActivityViewSet])
452
+ def test_assignee_can_see_private_activity_list(self, mvs, activity_factory, user_factory):
453
+ user = user_factory(is_active=True, is_superuser=True)
454
+ activity = activity_factory(
455
+ visibility=CalendarItem.Visibility.PRIVATE, assigned_to=user.profile, preceded_by=None
456
+ )
457
+ request = self.api_factory.get("")
458
+ request.user = user
459
+ view = mvs.as_view({"get": "list"})
460
+ response = view(request).render()
461
+ # Assert
462
+ assert response.status_code == status.HTTP_200_OK
463
+ assert response.data["results"]
464
+ assert len(response.data["results"]) == 1
465
+ assert response.data["results"][0]["id"] == activity.id
466
+ assert response.data["results"][0]["title"] == activity.title
467
+ assert response.data["results"][0]["type"] == activity.type.id
468
+ assert response.data["results"][0]["participants"] == list(
469
+ activity.participants.all().values_list("id", flat=True)
470
+ )
471
+ assert response.data["results"][0]["companies"] == list(activity.companies.all().values_list("id", flat=True))
472
+ assert response.data["results"][0]["groups"] == list(activity.groups.all().values_list("id", flat=True))
473
+ assert response.data["results"][0]["edited"] is not None
474
+ assert response.data["results"][0]["created"] is not None
475
+ assert response.data["results"][0]["description"] == activity.description
476
+ assert response.data["results"][0]["latest_reviewer"] == activity.latest_reviewer.id
477
+ if activity.status not in [Activity.Status.CANCELLED, Activity.Status.REVIEWED]:
478
+ assert response.data["results"][0]["_additional_resources"] is not None
479
+
480
+ @pytest.mark.parametrize("mvs", [ActivityViewSet])
481
+ def test_participant_can_see_private_activity_list(self, mvs, activity_factory, user_factory):
482
+ user = user_factory(is_active=True, is_superuser=True)
483
+ activity = activity_factory(
484
+ visibility=CalendarItem.Visibility.PRIVATE, participants=[user.profile.id], preceded_by=None
485
+ )
486
+ request = self.api_factory.get("")
487
+ request.user = user
488
+ view = mvs.as_view({"get": "list"})
489
+ response = view(request).render()
490
+ # Assert
491
+ assert response.status_code == status.HTTP_200_OK
492
+ assert response.data["results"]
493
+ assert len(response.data["results"]) == 1
494
+ assert response.data["results"][0]["id"] == activity.id
495
+ assert response.data["results"][0]["title"] == activity.title
496
+ assert response.data["results"][0]["type"] == activity.type.id
497
+ assert response.data["results"][0]["participants"] == list(
498
+ activity.participants.all().values_list("id", flat=True)
499
+ )
500
+ assert response.data["results"][0]["companies"] == list(activity.companies.all().values_list("id", flat=True))
501
+ assert response.data["results"][0]["groups"] == list(activity.groups.all().values_list("id", flat=True))
502
+ assert response.data["results"][0]["edited"] is not None
503
+ assert response.data["results"][0]["created"] is not None
504
+ assert response.data["results"][0]["description"] == activity.description
505
+ assert response.data["results"][0]["result"] == activity.result
506
+ assert response.data["results"][0]["latest_reviewer"] == activity.latest_reviewer.id
507
+ if activity.status not in [Activity.Status.CANCELLED, Activity.Status.REVIEWED]:
508
+ assert response.data["results"][0]["_additional_resources"] is not None
509
+
510
+ @pytest.mark.parametrize("mvs", [ActivityViewSet])
511
+ def test_random_cannot_see_private_activity_list(self, mvs, activity_factory, user_factory):
512
+ user = user_factory(is_active=True, is_superuser=True)
513
+ activity = activity_factory(visibility=CalendarItem.Visibility.PRIVATE, preceded_by=None)
514
+ request = self.api_factory.get("")
515
+ request.user = user
516
+ view = mvs.as_view({"get": "list"})
517
+ response = view(request).render()
518
+ # Assert
519
+ assert response.status_code == status.HTTP_200_OK
520
+ assert response.data["results"]
521
+ assert len(response.data["results"]) == 1
522
+ assert response.data["results"][0]["id"] == activity.id
523
+ assert response.data["results"][0]["title"] == "Private Activity"
524
+ assert response.data["results"][0]["type"] is None
525
+ assert response.data["results"][0]["edited"] is None
526
+ assert response.data["results"][0]["created"] is None
527
+ assert response.data["results"][0]["description"] is None
528
+ assert response.data["results"][0]["result"] is None
529
+ assert response.data["results"][0]["latest_reviewer"] is None
530
+ assert response.data["results"][0]["participants"] is not None
531
+ assert response.data["results"][0]["_participants"] is not None
532
+ assert response.data["results"][0]["companies"] is not None
533
+ assert response.data["results"][0]["_companies"] is not None
534
+ assert response.data["results"][0]["groups"] is not None
535
+ assert response.data["results"][0]["_groups"] is not None
536
+ assert response.data["results"][0]["_additional_resources"] is None
537
+
538
+ @pytest.mark.parametrize("mvs", [ActivityViewSet])
539
+ def test_assignee_can_see_private_activity_instance(self, mvs, activity_factory, user_factory):
540
+ user = user_factory(is_active=True, is_superuser=True)
541
+ activity = activity_factory(
542
+ visibility=CalendarItem.Visibility.PRIVATE, assigned_to=user.profile, preceded_by=None
543
+ )
544
+ request = self.api_factory.get("")
545
+ request.user = user
546
+ view = mvs.as_view({"get": "retrieve"})
547
+ response = view(request, pk=activity.id).render()
548
+ assert response.status_code == status.HTTP_200_OK
549
+ assert response.data.get("instance")
550
+ assert not response.data.get("results")
551
+ assert response.data["instance"]["id"] == activity.id
552
+ assert response.data["instance"]["title"] == activity.title
553
+ assert response.data["instance"]["participants"] == list(
554
+ activity.participants.all().values_list("id", flat=True)
555
+ )
556
+ assert response.data["instance"]["type"] == activity.type.id
557
+ assert response.data["instance"]["companies"] == list(activity.companies.all().values_list("id", flat=True))
558
+ assert response.data["instance"]["groups"] == list(activity.groups.all().values_list("id", flat=True))
559
+ assert response.data["instance"]["edited"] is not None
560
+ assert response.data["instance"]["created"] is not None
561
+ assert response.data["instance"]["description"] == activity.description
562
+ assert response.data["instance"]["result"] == activity.result
563
+ assert response.data["instance"]["latest_reviewer"] == activity.latest_reviewer.id
564
+ if activity.status not in [Activity.Status.CANCELLED, Activity.Status.REVIEWED]:
565
+ assert response.data["instance"]["_additional_resources"] is not None
566
+ assert response.data["instance"]["all_day"] == activity.all_day
567
+ assert response.data["instance"]["assigned_to"] == activity.assigned_to.id
568
+ assert response.data["instance"]["conference_room"] == activity.conference_room
569
+ assert response.data["instance"]["disable_participant_check"] == activity.disable_participant_check
570
+ assert response.data["instance"]["creator"] == activity.creator.id
571
+ assert response.data["instance"]["importance"] == activity.importance
572
+ assert response.data["instance"]["online_meeting"] == activity.online_meeting
573
+ assert response.data["instance"]["reminder_choice"] == activity.reminder_choice
574
+
575
+ @pytest.mark.parametrize("mvs", [ActivityViewSet])
576
+ def test_participant_can_see_private_activity_instance(self, mvs, activity_factory, user_factory):
577
+ user = user_factory(is_active=True, is_superuser=True)
578
+ activity = activity_factory(
579
+ visibility=CalendarItem.Visibility.PRIVATE, participants=[user.profile.id], preceded_by=None
580
+ )
581
+ request = self.api_factory.get("")
582
+ request.user = user
583
+ view = mvs.as_view({"get": "retrieve"})
584
+ response = view(request, pk=activity.id).render()
585
+ assert response.status_code == status.HTTP_200_OK
586
+ assert response.data.get("instance")
587
+ assert not response.data.get("results")
588
+ assert response.data["instance"]["id"] == activity.id
589
+ assert response.data["instance"]["title"] == activity.title
590
+ assert response.data["instance"]["participants"] == list(
591
+ activity.participants.all().values_list("id", flat=True)
592
+ )
593
+ assert response.data["instance"]["type"] == activity.type.id
594
+ assert response.data["instance"]["companies"] == list(activity.companies.all().values_list("id", flat=True))
595
+ assert response.data["instance"]["groups"] == list(activity.groups.all().values_list("id", flat=True))
596
+ assert response.data["instance"]["edited"] is not None
597
+ assert response.data["instance"]["created"] is not None
598
+ assert response.data["instance"]["description"] == activity.description
599
+ assert response.data["instance"]["result"] == activity.result
600
+ assert response.data["instance"]["latest_reviewer"] == activity.latest_reviewer.id
601
+ if activity.status not in [Activity.Status.CANCELLED, Activity.Status.REVIEWED]:
602
+ assert response.data["instance"]["_additional_resources"] is not None
603
+ assert response.data["instance"]["all_day"] == activity.all_day
604
+ assert response.data["instance"]["assigned_to"] == activity.assigned_to.id
605
+ assert response.data["instance"]["conference_room"] == activity.conference_room
606
+ assert response.data["instance"]["disable_participant_check"] == activity.disable_participant_check
607
+ assert response.data["instance"]["creator"] == activity.creator.id
608
+ assert response.data["instance"]["importance"] == activity.importance
609
+ assert response.data["instance"]["online_meeting"] == activity.online_meeting
610
+ assert response.data["instance"]["reminder_choice"] == activity.reminder_choice
611
+
612
+ @pytest.mark.parametrize("mvs", [ActivityViewSet])
613
+ def test_random_cannot_see_private_activity_instance(self, mvs, activity_factory, user_factory):
614
+ user = user_factory(is_active=True, is_superuser=True)
615
+ activity = activity_factory(visibility=CalendarItem.Visibility.PRIVATE, preceded_by=None)
616
+ request = self.api_factory.get("")
617
+ request.user = user
618
+ view = mvs.as_view({"get": "retrieve"})
619
+ response = view(request, pk=activity.id).render()
620
+ # Assert
621
+ assert response.status_code == status.HTTP_200_OK
622
+ assert response.data.get("instance")
623
+ assert not response.data.get("results")
624
+ assert response.data["instance"]["id"] == activity.id
625
+ assert response.data["instance"]["title"] == "Private Activity"
626
+ assert response.data["instance"]["participants"] is not None
627
+ assert response.data["instance"]["_participants"] is not None
628
+ assert response.data["instance"]["companies"] is not None
629
+ assert response.data["instance"]["_companies"] is not None
630
+ assert response.data["instance"]["groups"] is not None
631
+ assert response.data["instance"]["_groups"] is not None
632
+ assert response.data["instance"]["assigned_to"] is not None
633
+ assert response.data["instance"]["_assigned_to"] is not None
634
+ assert response.data["instance"]["creator"] is not None
635
+ assert response.data["instance"]["_creator"] is not None
636
+ assert response.data["instance"]["type"] is None
637
+ assert response.data["instance"]["_type"] is None
638
+ assert response.data["instance"]["edited"] is None
639
+ assert response.data["instance"]["created"] is None
640
+ assert response.data["instance"]["description"] is None
641
+ assert response.data["instance"]["result"] is None
642
+ assert response.data["instance"]["latest_reviewer"] is None
643
+ assert response.data["instance"]["_latest_reviewer"] is None
644
+ assert response.data["instance"]["_additional_resources"] is None
645
+ assert response.data["instance"]["all_day"] is None
646
+ assert response.data["instance"]["conference_room"] is None
647
+ assert response.data["instance"]["disable_participant_check"] is None
648
+ assert response.data["instance"]["importance"] is None
649
+ assert response.data["instance"]["location"] is None
650
+ assert response.data["instance"]["location_latitude"] is None
651
+ assert response.data["instance"]["location_longitude"] is None
652
+ assert response.data["instance"]["online_meeting"] is None
653
+ assert response.data["instance"]["reminder_choice"] is None
654
+ assert response.data["instance"]["reviewed_at"] is None
655
+
656
+ @pytest.mark.parametrize("mvs", [ActivityViewSet])
657
+ def test_private_instance_not_deleteable(self, mvs, activity_factory, user_factory):
658
+ activity = activity_factory(visibility=CalendarItem.Visibility.PRIVATE, preceded_by=None)
659
+ request = self.api_factory.delete("")
660
+ request.user = user_factory(is_active=True, is_superuser=True)
661
+ view = mvs.as_view({"delete": "destroy"})
662
+ response = view(request, pk=activity.id).render()
663
+ assert response.status_code == status.HTTP_405_METHOD_NOT_ALLOWED
664
+
665
+ @pytest.mark.parametrize("mvs", [ActivityViewSet])
666
+ def test_private_instance_deleteable_for_participant(self, mvs, activity_factory, user_factory):
667
+ superuser = user_factory(is_active=True, is_superuser=True)
668
+ activity = activity_factory(
669
+ visibility=CalendarItem.Visibility.PRIVATE, participants=[superuser.profile.id], preceded_by=None
670
+ )
671
+ request = self.api_factory.delete("")
672
+ request.user = superuser
673
+ view = mvs.as_view({"delete": "destroy"})
674
+ response = view(request, pk=activity.id).render()
675
+ assert response.status_code == status.HTTP_204_NO_CONTENT
676
+
677
+ @pytest.mark.parametrize("mvs", [ActivityViewSet])
678
+ def test_private_instance_deleteable_for_assignee(self, mvs, activity_factory, user_factory):
679
+ superuser = user_factory(is_active=True, is_superuser=True)
680
+ activity = activity_factory(
681
+ visibility=CalendarItem.Visibility.PRIVATE, assigned_to=superuser.profile, preceded_by=None
682
+ )
683
+ request = self.api_factory.delete("")
684
+ request.user = superuser
685
+ view = mvs.as_view({"delete": "destroy"})
686
+ response = view(request, pk=activity.id).render()
687
+ assert response.status_code == status.HTTP_204_NO_CONTENT
688
+
689
+ # =================================================================================================================
690
+ # TESTING CONFIDENTIAL ACTIVITIES
691
+ # =================================================================================================================
692
+
693
+ @pytest.mark.parametrize("mvs", [ActivityViewSet])
694
+ def test_manager_can_see_confidential_activity_list(self, mvs, activity_factory, user_factory):
695
+ user = user_factory(is_active=True, is_superuser=True)
696
+ permission = Permission.objects.get(codename="administrate_confidential_items")
697
+ user.user_permissions.add(permission)
698
+ activity = activity_factory(visibility=CalendarItem.Visibility.CONFIDENTIAL, preceded_by=None)
699
+ request = self.api_factory.get("")
700
+ request.user = user
701
+ view = mvs.as_view({"get": "list"})
702
+ response = view(request).render()
703
+ # Assert
704
+ assert response.status_code == status.HTTP_200_OK
705
+ assert response.data["results"]
706
+ assert len(response.data["results"]) == 1
707
+ assert response.data["results"][0]["id"] == activity.id
708
+ assert response.data["results"][0]["title"] == activity.title
709
+ assert response.data["results"][0]["participants"] == list(
710
+ activity.participants.all().values_list("id", flat=True)
711
+ )
712
+ assert response.data["results"][0]["companies"] == list(activity.companies.all().values_list("id", flat=True))
713
+ assert response.data["results"][0]["groups"] == list(activity.groups.all().values_list("id", flat=True))
714
+ assert response.data["results"][0]["type"] == activity.type.id
715
+ assert response.data["results"][0]["edited"] is not None
716
+ assert response.data["results"][0]["created"] is not None
717
+ assert response.data["results"][0]["description"] == activity.description
718
+ assert response.data["results"][0]["latest_reviewer"] == activity.latest_reviewer.id
719
+ if activity.status not in [Activity.Status.CANCELLED, Activity.Status.REVIEWED]:
720
+ assert response.data["results"][0]["_additional_resources"] is not None
721
+
722
+ @pytest.mark.parametrize("mvs", [ActivityViewSet])
723
+ def test_random_cannot_see_confidential_activity_list(self, mvs, activity_factory, user_factory):
724
+ user = user_factory(is_active=True, is_superuser=True)
725
+ activity = activity_factory(visibility=CalendarItem.Visibility.CONFIDENTIAL, preceded_by=None)
726
+ request = self.api_factory.get("")
727
+ request.user = user
728
+ view = mvs.as_view({"get": "list"})
729
+ response = view(request).render()
730
+ # Assert
731
+ assert response.status_code == status.HTTP_200_OK
732
+ assert response.data["results"]
733
+ assert len(response.data["results"]) == 1
734
+ assert response.data["results"][0]["id"] == activity.id
735
+ assert response.data["results"][0]["title"] == "Confidential Activity"
736
+ assert response.data["results"][0]["participants"] is None
737
+ assert response.data["results"][0]["companies"] is None
738
+ assert response.data["results"][0]["groups"] is None
739
+ assert response.data["results"][0]["type"] is None
740
+ assert response.data["results"][0]["edited"] is None
741
+ assert response.data["results"][0]["created"] is None
742
+ assert response.data["results"][0]["description"] is None
743
+ assert response.data["results"][0]["result"] is None
744
+ assert response.data["results"][0]["latest_reviewer"] is None
745
+ assert response.data["results"][0]["_additional_resources"] is None
746
+
747
+ @pytest.mark.parametrize("mvs", [ActivityViewSet])
748
+ def test_manager_can_see_confidential_activity_instance(self, mvs, activity_factory, user_factory):
749
+ user = user_factory(is_active=True, is_superuser=True)
750
+ permission = Permission.objects.get(codename="administrate_confidential_items")
751
+ user.user_permissions.add(permission)
752
+ activity = activity_factory(visibility=CalendarItem.Visibility.CONFIDENTIAL, preceded_by=None)
753
+ request = self.api_factory.get("")
754
+ request.user = user
755
+ view = mvs.as_view({"get": "retrieve"})
756
+ response = view(request, pk=activity.id).render()
757
+ assert response.status_code == status.HTTP_200_OK
758
+ assert response.data.get("instance")
759
+ assert not response.data.get("results")
760
+ assert response.data["instance"]["id"] == activity.id
761
+ assert response.data["instance"]["title"] == activity.title
762
+ assert response.data["instance"]["participants"] == list(
763
+ activity.participants.all().values_list("id", flat=True)
764
+ )
765
+ assert response.data["instance"]["type"] == activity.type.id
766
+ assert response.data["instance"]["companies"] == list(activity.companies.all().values_list("id", flat=True))
767
+ assert response.data["instance"]["groups"] == list(activity.groups.all().values_list("id", flat=True))
768
+ assert response.data["instance"]["edited"] is not None
769
+ assert response.data["instance"]["created"] is not None
770
+ assert response.data["instance"]["description"] == activity.description
771
+ assert response.data["instance"]["result"] == activity.result
772
+ assert response.data["instance"]["latest_reviewer"] == activity.latest_reviewer.id
773
+ if activity.status not in [Activity.Status.CANCELLED, Activity.Status.REVIEWED]:
774
+ assert response.data["instance"]["_additional_resources"] is not None
775
+ assert response.data["instance"]["all_day"] == activity.all_day
776
+ assert response.data["instance"]["assigned_to"] == activity.assigned_to.id
777
+ assert response.data["instance"]["conference_room"] == activity.conference_room
778
+ assert response.data["instance"]["disable_participant_check"] == activity.disable_participant_check
779
+ assert response.data["instance"]["creator"] == activity.creator.id
780
+ assert response.data["instance"]["importance"] == activity.importance
781
+ assert response.data["instance"]["online_meeting"] == activity.online_meeting
782
+ assert response.data["instance"]["reminder_choice"] == activity.reminder_choice
783
+
784
+ @pytest.mark.parametrize("mvs", [ActivityViewSet])
785
+ def test_random_cannot_see_confidential_activity_instance(self, mvs, activity_factory, user_factory):
786
+ user = user_factory(is_active=True, is_superuser=True)
787
+ activity = activity_factory(visibility=CalendarItem.Visibility.CONFIDENTIAL, preceded_by=None)
788
+ request = self.api_factory.get("")
789
+ request.user = user
790
+ view = mvs.as_view({"get": "retrieve"})
791
+ response = view(request, pk=activity.id).render()
792
+ # Assert
793
+ assert response.status_code == status.HTTP_200_OK
794
+ assert response.data.get("instance")
795
+ assert not response.data.get("results")
796
+ assert response.data["instance"]["id"] == activity.id
797
+ assert response.data["instance"]["title"] == "Confidential Activity"
798
+ assert response.data["instance"]["participants"] is None
799
+ assert response.data["instance"]["_participants"] is None
800
+ assert response.data["instance"]["type"] is None
801
+ assert response.data["instance"]["_type"] is None
802
+ assert response.data["instance"]["companies"] is None
803
+ assert response.data["instance"]["_companies"] is None
804
+ assert response.data["instance"]["groups"] is None
805
+ assert response.data["instance"]["_groups"] is None
806
+ assert response.data["instance"]["edited"] is None
807
+ assert response.data["instance"]["created"] is None
808
+ assert response.data["instance"]["description"] is None
809
+ assert response.data["instance"]["result"] is None
810
+ assert response.data["instance"]["latest_reviewer"] is None
811
+ assert response.data["instance"]["_latest_reviewer"] is None
812
+ assert response.data["instance"]["_additional_resources"] is None
813
+ assert response.data["instance"]["all_day"] is None
814
+ assert response.data["instance"]["assigned_to"] is None
815
+ assert response.data["instance"]["conference_room"] is None
816
+ assert response.data["instance"]["disable_participant_check"] is None
817
+ assert response.data["instance"]["creator"] is None
818
+ assert response.data["instance"]["importance"] is None
819
+ assert response.data["instance"]["location"] is None
820
+ assert response.data["instance"]["location_latitude"] is None
821
+ assert response.data["instance"]["location_longitude"] is None
822
+ assert response.data["instance"]["online_meeting"] is None
823
+ assert response.data["instance"]["reminder_choice"] is None
824
+ assert response.data["instance"]["reviewed_at"] is None
825
+ assert response.data["instance"]["_assigned_to"] is None
826
+ assert response.data["instance"]["_creator"] is None
827
+
828
+ @pytest.mark.parametrize("mvs", [ActivityViewSet])
829
+ def test_confidential_instance_not_deleteable(self, mvs, activity_factory, internal_user_factory, user_factory):
830
+ employee = internal_user_factory().profile
831
+ user = user_factory(is_active=True)
832
+ employee.user_account = user
833
+ for permission in Permission.objects.exclude(codename="administrate_confidential_items"):
834
+ user.user_permissions.add(permission)
835
+ global_preferences_registry.manager()["directory__main_company"] = employee.employers.first().id
836
+ activity = activity_factory(visibility=CalendarItem.Visibility.CONFIDENTIAL, preceded_by=None)
837
+ request = self.api_factory.delete("")
838
+ request.user = user
839
+ view = mvs.as_view({"delete": "destroy"})
840
+ response = view(request, pk=activity.id).render()
841
+ assert response.status_code == status.HTTP_405_METHOD_NOT_ALLOWED
842
+
843
+
844
+ # =====================================================================================================================
845
+ # TESTING ENTRY VIEWSETS
846
+ # =====================================================================================================================
847
+
848
+
849
+ # # =====================================================================================================================
850
+ # # TESTING UTILS VIEWSETS
851
+ # # =====================================================================================================================
852
+
853
+
854
+ @pytest.mark.django_db
855
+ class TestUtilsViewSets:
856
+ api_factory = APIRequestFactory()
857
+
858
+ @pytest.mark.parametrize(
859
+ "mvs",
860
+ [
861
+ ActivityTypeModelViewSet,
862
+ ProductModelViewSet,
863
+ ],
864
+ )
865
+ def test_get_utils(self, mvs):
866
+ request = self.api_factory.get("")
867
+ request.user = InternalUserFactory(is_active=True, is_superuser=True)
868
+ factory = get_model_factory(mvs().get_serializer_class().Meta.model)
869
+ factory.create_batch(3)
870
+ vs = mvs.as_view({"get": "list"})
871
+ response = vs(request)
872
+ assert response.data.get("results")
873
+ assert not response.data.get("instance")
874
+ assert len(response.data.get("results")) == 3
875
+ assert response.status_code == status.HTTP_200_OK
876
+
877
+ @pytest.mark.parametrize(
878
+ "mvs",
879
+ [
880
+ ActivityTypeModelViewSet,
881
+ ProductModelViewSet,
882
+ ],
883
+ )
884
+ def test_retrieve_utils(self, mvs):
885
+ request = self.api_factory.get("")
886
+ request.user = InternalUserFactory(is_active=True, is_superuser=True)
887
+ factory = get_model_factory(mvs().get_serializer_class().Meta.model)
888
+ obj = factory()
889
+ vs = mvs.as_view({"get": "retrieve"})
890
+ response = vs(request, pk=obj.id)
891
+ assert response.data.get("instance")
892
+ assert not response.data.get("results")
893
+ assert response.status_code == status.HTTP_200_OK
894
+
895
+ @pytest.mark.parametrize(
896
+ "mvs",
897
+ [
898
+ ActivityTypeModelViewSet,
899
+ ProductModelViewSet,
900
+ ],
901
+ )
902
+ def test_post_utils(self, mvs):
903
+ factory = get_model_factory(mvs().get_serializer_class().Meta.model)
904
+ obj = factory()
905
+ super_user = InternalUserFactory(is_active=True, is_superuser=True)
906
+ data = get_data_from_factory(obj, mvs, superuser=super_user, delete=True)
907
+ request = self.api_factory.post("", data=data)
908
+ request.user = super_user
909
+ kwargs = get_kwargs(obj, mvs, request)
910
+ vs = mvs.as_view({"post": "create"})
911
+ response = vs(request, **kwargs)
912
+ assert response.status_code == status.HTTP_201_CREATED
913
+
914
+ @pytest.mark.parametrize(
915
+ "mvs",
916
+ [
917
+ ActivityTypeModelViewSet,
918
+ ProductModelViewSet,
919
+ ],
920
+ )
921
+ def test_delete_utils(self, mvs):
922
+ request = self.api_factory.delete("")
923
+ request.user = InternalUserFactory(is_active=True, is_superuser=True)
924
+ factory = get_model_factory(mvs().get_serializer_class().Meta.model)
925
+ obj = factory()
926
+ kwargs = get_kwargs(obj, mvs, request)
927
+ vs = mvs.as_view({"delete": "destroy"})
928
+ response = vs(request, **kwargs, pk=obj.pk)
929
+ assert response.status_code == status.HTTP_204_NO_CONTENT
930
+
931
+ @pytest.mark.parametrize(
932
+ "mvs",
933
+ [
934
+ ActivityTypeModelViewSet,
935
+ ProductModelViewSet,
936
+ ],
937
+ )
938
+ def test_put_utils(self, mvs):
939
+ factory = get_model_factory(mvs().get_serializer_class().Meta.model)
940
+ old_obj = factory()
941
+ new_obj = factory()
942
+ user = InternalUserFactory(is_active=True, is_superuser=True)
943
+ data = get_data_from_factory(new_obj, mvs, superuser=user, delete=True)
944
+ request = APIRequestFactory().put("", data=data)
945
+ request.user = user
946
+ vs = mvs.as_view({"put": "update"})
947
+ response = vs(request, pk=old_obj.id)
948
+ assert response.status_code == status.HTTP_200_OK
949
+ assert response.data["instance"]["title"] == new_obj.title
950
+ assert not response.data["instance"]["title"] == old_obj.title
951
+
952
+ @pytest.mark.parametrize(
953
+ "mvs",
954
+ [
955
+ ActivityTypeModelViewSet,
956
+ ProductModelViewSet,
957
+ ],
958
+ )
959
+ def test_patch_utils(self, mvs):
960
+ factory = get_model_factory(mvs().get_serializer_class().Meta.model)
961
+ obj = factory()
962
+ request = APIRequestFactory().patch("", data={"title": "New Title"})
963
+ request.user = InternalUserFactory(is_active=True, is_superuser=True)
964
+ vs = mvs.as_view({"patch": "partial_update"})
965
+ response = vs(request, pk=obj.id)
966
+ assert response.status_code == status.HTTP_200_OK
967
+ assert response.data["instance"]["title"] == "New Title"