wbcrm 1.56.8__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.
- wbcrm/__init__.py +1 -0
- wbcrm/admin/__init__.py +5 -0
- wbcrm/admin/accounts.py +60 -0
- wbcrm/admin/activities.py +104 -0
- wbcrm/admin/events.py +43 -0
- wbcrm/admin/groups.py +8 -0
- wbcrm/admin/products.py +9 -0
- wbcrm/apps.py +5 -0
- wbcrm/configurations/__init__.py +1 -0
- wbcrm/configurations/base.py +16 -0
- wbcrm/dynamic_preferences_registry.py +38 -0
- wbcrm/factories/__init__.py +14 -0
- wbcrm/factories/accounts.py +57 -0
- wbcrm/factories/activities.py +124 -0
- wbcrm/factories/groups.py +24 -0
- wbcrm/factories/products.py +11 -0
- wbcrm/filters/__init__.py +10 -0
- wbcrm/filters/accounts.py +80 -0
- wbcrm/filters/activities.py +204 -0
- wbcrm/filters/groups.py +21 -0
- wbcrm/filters/products.py +38 -0
- wbcrm/filters/signals.py +95 -0
- wbcrm/fixtures/wbcrm.json +1215 -0
- wbcrm/kpi_handlers/activities.py +171 -0
- wbcrm/locale/de/LC_MESSAGES/django.mo +0 -0
- wbcrm/locale/de/LC_MESSAGES/django.po +1557 -0
- wbcrm/locale/de/LC_MESSAGES/django.po.translated +1630 -0
- wbcrm/locale/en/LC_MESSAGES/django.mo +0 -0
- wbcrm/locale/en/LC_MESSAGES/django.po +1466 -0
- wbcrm/locale/fr/LC_MESSAGES/django.mo +0 -0
- wbcrm/locale/fr/LC_MESSAGES/django.po +1467 -0
- wbcrm/migrations/0001_initial_squashed_squashed_0032_productcompanyrelationship_alter_product_prospects_and_more.py +3948 -0
- wbcrm/migrations/0002_alter_activity_repeat_choice.py +32 -0
- wbcrm/migrations/0003_remove_activity_external_id_and_more.py +63 -0
- wbcrm/migrations/0004_alter_activity_status.py +28 -0
- wbcrm/migrations/0005_account_accountrole_accountroletype_and_more.py +182 -0
- wbcrm/migrations/0006_alter_activity_location.py +17 -0
- wbcrm/migrations/0007_alter_account_status.py +23 -0
- wbcrm/migrations/0008_alter_activity_options.py +16 -0
- wbcrm/migrations/0009_alter_account_is_public.py +19 -0
- wbcrm/migrations/0010_alter_account_reference_id.py +17 -0
- wbcrm/migrations/0011_activity_summary.py +22 -0
- wbcrm/migrations/0012_alter_activity_summary.py +17 -0
- wbcrm/migrations/0013_account_action_plan_account_relationship_status_and_more.py +34 -0
- wbcrm/migrations/0014_alter_account_relationship_status.py +24 -0
- wbcrm/migrations/0015_alter_activity_type.py +23 -0
- wbcrm/migrations/0016_auto_20241205_1015.py +106 -0
- wbcrm/migrations/0017_event.py +40 -0
- wbcrm/migrations/0018_activity_search_vector.py +24 -0
- wbcrm/migrations/__init__.py +0 -0
- wbcrm/models/__init__.py +5 -0
- wbcrm/models/accounts.py +648 -0
- wbcrm/models/activities.py +1419 -0
- wbcrm/models/events.py +15 -0
- wbcrm/models/groups.py +119 -0
- wbcrm/models/llm/activity_summaries.py +41 -0
- wbcrm/models/llm/analyze_relationship.py +50 -0
- wbcrm/models/products.py +86 -0
- wbcrm/models/recurrence.py +280 -0
- wbcrm/preferences.py +13 -0
- wbcrm/report/activity_report.py +110 -0
- wbcrm/serializers/__init__.py +23 -0
- wbcrm/serializers/accounts.py +141 -0
- wbcrm/serializers/activities.py +525 -0
- wbcrm/serializers/groups.py +30 -0
- wbcrm/serializers/products.py +58 -0
- wbcrm/serializers/recurrence.py +91 -0
- wbcrm/serializers/signals.py +71 -0
- wbcrm/static/wbcrm/markdown/documentation/activity.md +86 -0
- wbcrm/static/wbcrm/markdown/documentation/activitytype.md +20 -0
- wbcrm/static/wbcrm/markdown/documentation/group.md +2 -0
- wbcrm/static/wbcrm/markdown/documentation/product.md +11 -0
- wbcrm/synchronization/__init__.py +0 -0
- wbcrm/synchronization/activity/__init__.py +0 -0
- wbcrm/synchronization/activity/admin.py +73 -0
- wbcrm/synchronization/activity/backend.py +214 -0
- wbcrm/synchronization/activity/backends/__init__.py +0 -0
- wbcrm/synchronization/activity/backends/google/__init__.py +2 -0
- wbcrm/synchronization/activity/backends/google/google_calendar_backend.py +406 -0
- wbcrm/synchronization/activity/backends/google/request_utils/__init__.py +16 -0
- wbcrm/synchronization/activity/backends/google/request_utils/external_to_internal/create.py +75 -0
- wbcrm/synchronization/activity/backends/google/request_utils/external_to_internal/delete.py +78 -0
- wbcrm/synchronization/activity/backends/google/request_utils/external_to_internal/update.py +155 -0
- wbcrm/synchronization/activity/backends/google/request_utils/internal_to_external/update.py +181 -0
- wbcrm/synchronization/activity/backends/google/tasks.py +21 -0
- wbcrm/synchronization/activity/backends/google/tests/__init__.py +0 -0
- wbcrm/synchronization/activity/backends/google/tests/conftest.py +1 -0
- wbcrm/synchronization/activity/backends/google/tests/test_data.py +81 -0
- wbcrm/synchronization/activity/backends/google/tests/test_google_backend.py +319 -0
- wbcrm/synchronization/activity/backends/google/tests/test_utils.py +274 -0
- wbcrm/synchronization/activity/backends/google/typing_informations.py +139 -0
- wbcrm/synchronization/activity/backends/google/utils.py +217 -0
- wbcrm/synchronization/activity/backends/outlook/__init__.py +0 -0
- wbcrm/synchronization/activity/backends/outlook/backend.py +593 -0
- wbcrm/synchronization/activity/backends/outlook/msgraph.py +436 -0
- wbcrm/synchronization/activity/backends/outlook/parser.py +432 -0
- wbcrm/synchronization/activity/backends/outlook/tests/__init__.py +0 -0
- wbcrm/synchronization/activity/backends/outlook/tests/conftest.py +1 -0
- wbcrm/synchronization/activity/backends/outlook/tests/fixtures.py +606 -0
- wbcrm/synchronization/activity/backends/outlook/tests/test_admin.py +118 -0
- wbcrm/synchronization/activity/backends/outlook/tests/test_backend.py +274 -0
- wbcrm/synchronization/activity/backends/outlook/tests/test_controller.py +249 -0
- wbcrm/synchronization/activity/backends/outlook/tests/test_parser.py +174 -0
- wbcrm/synchronization/activity/controller.py +627 -0
- wbcrm/synchronization/activity/dynamic_preferences_registry.py +119 -0
- wbcrm/synchronization/activity/preferences.py +27 -0
- wbcrm/synchronization/activity/shortcuts.py +16 -0
- wbcrm/synchronization/activity/tasks.py +21 -0
- wbcrm/synchronization/activity/urls.py +7 -0
- wbcrm/synchronization/activity/utils.py +46 -0
- wbcrm/synchronization/activity/views.py +41 -0
- wbcrm/synchronization/admin.py +1 -0
- wbcrm/synchronization/apps.py +14 -0
- wbcrm/synchronization/dynamic_preferences_registry.py +1 -0
- wbcrm/synchronization/management.py +36 -0
- wbcrm/synchronization/tasks.py +1 -0
- wbcrm/synchronization/urls.py +5 -0
- wbcrm/tasks.py +264 -0
- wbcrm/templates/email/activity.html +98 -0
- wbcrm/templates/email/activity_report.html +6 -0
- wbcrm/templates/email/daily_summary.html +72 -0
- wbcrm/templates/email/global_daily_summary.html +85 -0
- wbcrm/tests/__init__.py +0 -0
- wbcrm/tests/accounts/__init__.py +0 -0
- wbcrm/tests/accounts/test_models.py +393 -0
- wbcrm/tests/accounts/test_viewsets.py +88 -0
- wbcrm/tests/conftest.py +76 -0
- wbcrm/tests/disable_signals.py +62 -0
- wbcrm/tests/e2e/__init__.py +1 -0
- wbcrm/tests/e2e/e2e_wbcrm_utility.py +83 -0
- wbcrm/tests/e2e/test_e2e.py +370 -0
- wbcrm/tests/test_assignee_methods.py +40 -0
- wbcrm/tests/test_chartviewsets.py +112 -0
- wbcrm/tests/test_dto.py +64 -0
- wbcrm/tests/test_filters.py +52 -0
- wbcrm/tests/test_models.py +217 -0
- wbcrm/tests/test_recurrence.py +292 -0
- wbcrm/tests/test_report.py +21 -0
- wbcrm/tests/test_serializers.py +171 -0
- wbcrm/tests/test_tasks.py +95 -0
- wbcrm/tests/test_viewsets.py +967 -0
- wbcrm/tests/tests.py +121 -0
- wbcrm/typings.py +109 -0
- wbcrm/urls.py +67 -0
- wbcrm/viewsets/__init__.py +22 -0
- wbcrm/viewsets/accounts.py +122 -0
- wbcrm/viewsets/activities.py +341 -0
- wbcrm/viewsets/buttons/__init__.py +7 -0
- wbcrm/viewsets/buttons/accounts.py +27 -0
- wbcrm/viewsets/buttons/activities.py +89 -0
- wbcrm/viewsets/buttons/signals.py +17 -0
- wbcrm/viewsets/display/__init__.py +12 -0
- wbcrm/viewsets/display/accounts.py +110 -0
- wbcrm/viewsets/display/activities.py +444 -0
- wbcrm/viewsets/display/groups.py +22 -0
- wbcrm/viewsets/display/products.py +105 -0
- wbcrm/viewsets/endpoints/__init__.py +8 -0
- wbcrm/viewsets/endpoints/accounts.py +25 -0
- wbcrm/viewsets/endpoints/activities.py +30 -0
- wbcrm/viewsets/endpoints/groups.py +7 -0
- wbcrm/viewsets/endpoints/products.py +9 -0
- wbcrm/viewsets/groups.py +38 -0
- wbcrm/viewsets/menu/__init__.py +8 -0
- wbcrm/viewsets/menu/accounts.py +18 -0
- wbcrm/viewsets/menu/activities.py +49 -0
- wbcrm/viewsets/menu/groups.py +16 -0
- wbcrm/viewsets/menu/products.py +20 -0
- wbcrm/viewsets/mixins.py +35 -0
- wbcrm/viewsets/previews/__init__.py +1 -0
- wbcrm/viewsets/previews/activities.py +10 -0
- wbcrm/viewsets/products.py +57 -0
- wbcrm/viewsets/recurrence.py +27 -0
- wbcrm/viewsets/titles/__init__.py +13 -0
- wbcrm/viewsets/titles/accounts.py +23 -0
- wbcrm/viewsets/titles/activities.py +61 -0
- wbcrm/viewsets/titles/products.py +13 -0
- wbcrm/viewsets/titles/utils.py +46 -0
- wbcrm/workflows/__init__.py +1 -0
- wbcrm/workflows/assignee_methods.py +25 -0
- wbcrm-1.56.8.dist-info/METADATA +11 -0
- wbcrm-1.56.8.dist-info/RECORD +182 -0
- wbcrm-1.56.8.dist-info/WHEEL +5 -0
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
# import datetime
|
|
2
|
+
# import json
|
|
3
|
+
# from unittest.mock import patch
|
|
4
|
+
|
|
5
|
+
# import pytest
|
|
6
|
+
# from django.utils import timezone
|
|
7
|
+
# from dynamic_preferences.registries import global_preferences_registry
|
|
8
|
+
# from rest_framework.test import APIRequestFactory
|
|
9
|
+
# from wbcore.test.utils import get_or_create_superuser
|
|
10
|
+
# from wbcrm.models import ActivityParticipant
|
|
11
|
+
|
|
12
|
+
# from ..google_calendar_backend import GoogleCalendarBackend
|
|
13
|
+
# from .test_data import credentials, event_data, ExecuteService, ServiceData
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
# class TestInitialisationGoogleCalendarBackend:
|
|
17
|
+
# @pytest.fixture()
|
|
18
|
+
# def activity_with_user(self, activity_factory):
|
|
19
|
+
# user = get_or_create_superuser()
|
|
20
|
+
# user.metadata = {"google_backend": {"watch": {"id": "fake_id"}}}
|
|
21
|
+
# user.save()
|
|
22
|
+
# return activity_factory(creator=user.profile)
|
|
23
|
+
|
|
24
|
+
# @pytest.fixture()
|
|
25
|
+
# def activity_with_user2(self, activity_factory):
|
|
26
|
+
# user = get_or_create_superuser()
|
|
27
|
+
# user.metadata = {"google_backend": {"watch": {"id": "fake_id2"}}}
|
|
28
|
+
# user.save()
|
|
29
|
+
# return activity_factory(creator=user.profile)
|
|
30
|
+
|
|
31
|
+
# @pytest.mark.parametrize("credentials", ["", credentials])
|
|
32
|
+
# def test_get_service_account_file(self, credentials):
|
|
33
|
+
# from ..google_calendar_backend import GoogleCalendarBackend
|
|
34
|
+
|
|
35
|
+
# global_preferences_registry.manager()["wbactivity_sync__google_sync_credentials"] = credentials
|
|
36
|
+
|
|
37
|
+
# backend = GoogleCalendarBackend()
|
|
38
|
+
|
|
39
|
+
# if not credentials:
|
|
40
|
+
# with pytest.raises(ValueError) as excinfo:
|
|
41
|
+
# file = backend._get_service_account_file()
|
|
42
|
+
# assert (
|
|
43
|
+
# "The Google credentials are not set. You cannot use the Google Calendar Backend without the Google credentials."
|
|
44
|
+
# in str(excinfo.value)
|
|
45
|
+
# )
|
|
46
|
+
# else:
|
|
47
|
+
# file = backend._get_service_account_file()
|
|
48
|
+
# assert file == json.loads(credentials)
|
|
49
|
+
|
|
50
|
+
# @pytest.mark.parametrize("credentials", [credentials])
|
|
51
|
+
# def test_get_service_account_url(self, credentials):
|
|
52
|
+
# from ..google_calendar_backend import GoogleCalendarBackend
|
|
53
|
+
|
|
54
|
+
# global_preferences_registry.manager()["wbactivity_sync__google_sync_credentials"] = credentials
|
|
55
|
+
# assert GoogleCalendarBackend()._get_service_account_url()
|
|
56
|
+
|
|
57
|
+
# def test_get_service_user_email(self, activity_with_user, activity_with_user2, activity_factory):
|
|
58
|
+
# global_preferences_registry.manager()["wbcrm__main_company"] = employee.employers.first().id
|
|
59
|
+
|
|
60
|
+
# activity = activity_factory()
|
|
61
|
+
# activity1 = activity_factory()
|
|
62
|
+
# activity2 = activity_with_user2
|
|
63
|
+
# activity3 = activity_with_user
|
|
64
|
+
# activity4 = activity_factory(participants=(employee,))
|
|
65
|
+
# tomorrow = (timezone.now() + datetime.timedelta(days=1)).replace(tzinfo=None)
|
|
66
|
+
# activity3.creator.user_account.metadata["google_backend"]["watch"]["expiration"] = (
|
|
67
|
+
# datetime.datetime.timestamp(tomorrow) * 1000
|
|
68
|
+
# )
|
|
69
|
+
# activity3.creator.user_account.save()
|
|
70
|
+
# employee.user_account.metadata = activity3.creator.user_account.metadata
|
|
71
|
+
# employee.user_account.save()
|
|
72
|
+
# backend = GoogleCalendarBackend()
|
|
73
|
+
# assert backend._get_service_user_email(activity) == ""
|
|
74
|
+
# assert backend._get_service_user_email(activity1) == ""
|
|
75
|
+
# assert backend._get_service_user_email(activity2) == ""
|
|
76
|
+
# assert backend._get_service_user_email(activity3) == activity3.creator.user_account.email
|
|
77
|
+
# assert backend._get_service_user_email(activity4)
|
|
78
|
+
|
|
79
|
+
# @patch("wbcrm.synchronization.activity.backends.google.google_calendar_backend.Credentials")
|
|
80
|
+
# @patch("wbcrm.synchronization.activity.backends.google.google_calendar_backend.build")
|
|
81
|
+
# @pytest.mark.parametrize("credentials", ["", credentials])
|
|
82
|
+
# def test_build_service(self, mock_build, mock_credentials, credentials):
|
|
83
|
+
# global_preferences_registry.manager()["wbactivity_sync__google_sync_credentials"] = credentials
|
|
84
|
+
# user = get_or_create_superuser()
|
|
85
|
+
# backend = GoogleCalendarBackend()
|
|
86
|
+
# if not credentials:
|
|
87
|
+
# with pytest.raises(ValueError) as excinfo:
|
|
88
|
+
# resource = backend._build_service(user.email)
|
|
89
|
+
# assert backend.error_messages["service_build_error"] in str(excinfo.value)
|
|
90
|
+
# else:
|
|
91
|
+
# resource = backend._build_service(user.email)
|
|
92
|
+
# assert resource
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
# @patch("wbcrm.synchronization.activity.backends.google.google_calendar_backend.GoogleCalendarBackend._build_service")
|
|
96
|
+
# @patch(
|
|
97
|
+
# "wbcrm.synchronization.activity.backends.google.google_calendar_backend.GoogleCalendarBackend._get_service_user_email"
|
|
98
|
+
# )
|
|
99
|
+
# @pytest.mark.parametrize(
|
|
100
|
+
# "sync_past_activity, event", [(False, ""), (True, ""), (False, event_data), (True, event_data)]
|
|
101
|
+
# )
|
|
102
|
+
# @pytest.mark.django_db
|
|
103
|
+
# class TestGoogleCalendarBackend:
|
|
104
|
+
# @pytest.fixture()
|
|
105
|
+
# def activity_fixture(self, activity_factory, event):
|
|
106
|
+
# user = get_or_create_superuser()
|
|
107
|
+
# user.metadata = {"google_backend": {"watch": {"id": "fake_id"}}}
|
|
108
|
+
# user.save()
|
|
109
|
+
# if event:
|
|
110
|
+
# metadata = {"google_backend": {"event": event}}
|
|
111
|
+
# return activity_factory(creator=user.profile, metadata=metadata, external_id=event["id"])
|
|
112
|
+
# else:
|
|
113
|
+
# metadata = {}
|
|
114
|
+
# return activity_factory(creator=user.profile, metadata=metadata, external_id=None)
|
|
115
|
+
|
|
116
|
+
# def test_create_external_activity(
|
|
117
|
+
# self, mock_user_email, mock_service, sync_past_activity, event, activity_factory
|
|
118
|
+
# ):
|
|
119
|
+
# global_preferences_registry.manager()["wbactivity_sync__sync_past_activity"] = sync_past_activity
|
|
120
|
+
# now = timezone.now()
|
|
121
|
+
# yesterday = now - datetime.timedelta(days=1)
|
|
122
|
+
# tomorrow = now + datetime.timedelta(days=1)
|
|
123
|
+
|
|
124
|
+
# activity_passed = activity_factory(start=yesterday, end=yesterday + datetime.timedelta(hours=1))
|
|
125
|
+
# activity = activity_factory(start=tomorrow, end=tomorrow + datetime.timedelta(hours=1))
|
|
126
|
+
# activity_with_parent = activity_factory(
|
|
127
|
+
# start=tomorrow, end=tomorrow + datetime.timedelta(hours=1), parent_occurrence=activity_passed
|
|
128
|
+
# )
|
|
129
|
+
|
|
130
|
+
# mock_service.return_value = service_data()
|
|
131
|
+
# with patch.object(ExecuteService, "execute", return_value=event):
|
|
132
|
+
|
|
133
|
+
# backend = GoogleCalendarBackend()
|
|
134
|
+
# if event:
|
|
135
|
+
# backend.create_external_activity(activity_passed)
|
|
136
|
+
# backend.create_external_activity(activity)
|
|
137
|
+
# backend.create_external_activity(activity_with_parent)
|
|
138
|
+
# assert (
|
|
139
|
+
# mock_service.call_count == 2
|
|
140
|
+
# ) # 2 instead of 3 because an activity with a parent cannot be synchronized
|
|
141
|
+
|
|
142
|
+
# else:
|
|
143
|
+
# with pytest.raises(ValueError) as excinfo:
|
|
144
|
+
# backend.create_external_activity(activity_passed)
|
|
145
|
+
# backend.create_external_activity(activity)
|
|
146
|
+
# backend.create_external_activity(activity_with_parent)
|
|
147
|
+
# assert "Could not create the external google event. Exception" in str(excinfo.value)
|
|
148
|
+
|
|
149
|
+
# if sync_past_activity:
|
|
150
|
+
# assert mock_service.call_count == 1
|
|
151
|
+
# else:
|
|
152
|
+
# assert mock_service.call_count == 1
|
|
153
|
+
# activity_passed.refresh_from_db()
|
|
154
|
+
# activity.refresh_from_db()
|
|
155
|
+
# activity_with_parent.refresh_from_db()
|
|
156
|
+
|
|
157
|
+
# assert activity_with_parent.metadata == {}
|
|
158
|
+
# assert activity_with_parent.external_id is None
|
|
159
|
+
|
|
160
|
+
# if event:
|
|
161
|
+
# assert activity.metadata
|
|
162
|
+
# assert activity.external_id == event["id"]
|
|
163
|
+
# else:
|
|
164
|
+
# assert activity.metadata == {}
|
|
165
|
+
# assert activity.external_id is None
|
|
166
|
+
|
|
167
|
+
# if sync_past_activity and event:
|
|
168
|
+
# assert activity_passed.metadata
|
|
169
|
+
# assert activity_passed.external_id == event["id"]
|
|
170
|
+
# else:
|
|
171
|
+
# assert activity_passed.metadata == {}
|
|
172
|
+
# assert activity_passed.external_id is None
|
|
173
|
+
|
|
174
|
+
# def test_delete_external_activity(
|
|
175
|
+
# self, mock_user_email, mock_service, sync_past_activity, event, activity_factory
|
|
176
|
+
# ):
|
|
177
|
+
# global_preferences_registry.manager()["wbactivity_sync__sync_past_activity"] = sync_past_activity
|
|
178
|
+
# now = timezone.now()
|
|
179
|
+
# yesterday = now - datetime.timedelta(days=1)
|
|
180
|
+
# tomorrow = now + datetime.timedelta(days=1)
|
|
181
|
+
|
|
182
|
+
# activity_passed = activity_factory(start=yesterday, end=yesterday + datetime.timedelta(hours=1))
|
|
183
|
+
# activity = activity_factory(start=tomorrow, end=tomorrow + datetime.timedelta(hours=1))
|
|
184
|
+
# activity_with_parent = activity_factory(
|
|
185
|
+
# start=tomorrow, end=tomorrow + datetime.timedelta(hours=1), parent_occurrence=activity_passed
|
|
186
|
+
# )
|
|
187
|
+
|
|
188
|
+
# mock_service.return_value = service_data()
|
|
189
|
+
# with patch.object(ExecuteService, "execute", return_value=None):
|
|
190
|
+
|
|
191
|
+
# backend = GoogleCalendarBackend()
|
|
192
|
+
# backend.delete_external_activity(activity_passed)
|
|
193
|
+
# backend.delete_external_activity(activity)
|
|
194
|
+
# backend.delete_external_activity(activity_with_parent)
|
|
195
|
+
# assert mock_service.call_count == 3
|
|
196
|
+
|
|
197
|
+
# def test_update_external_activity(
|
|
198
|
+
# self, mock_user_email, mock_service, sync_past_activity, event, activity_factory
|
|
199
|
+
# ):
|
|
200
|
+
# global_preferences_registry.manager()["wbactivity_sync__sync_past_activity"] = sync_past_activity
|
|
201
|
+
# now = timezone.now()
|
|
202
|
+
# yesterday = now - datetime.timedelta(days=1)
|
|
203
|
+
# tomorrow = now + datetime.timedelta(days=1)
|
|
204
|
+
|
|
205
|
+
# metadata = {"google_backend": {"instance": event if event else {}}}
|
|
206
|
+
# external_id = event["id"] if event else None
|
|
207
|
+
# activity_no_metadata = activity_factory(start=tomorrow, end=tomorrow + datetime.timedelta(hours=1))
|
|
208
|
+
# activity_passed = activity_factory(
|
|
209
|
+
# start=yesterday, end=yesterday + datetime.timedelta(hours=1), external_id=external_id, metadata=metadata
|
|
210
|
+
# )
|
|
211
|
+
# activity = activity_factory(
|
|
212
|
+
# start=tomorrow, end=tomorrow + datetime.timedelta(hours=1), external_id=external_id, metadata=metadata
|
|
213
|
+
# )
|
|
214
|
+
# activity_with_parent = activity_factory(
|
|
215
|
+
# start=tomorrow,
|
|
216
|
+
# end=tomorrow + datetime.timedelta(hours=1),
|
|
217
|
+
# parent_occurrence=activity_passed,
|
|
218
|
+
# external_id=external_id,
|
|
219
|
+
# metadata=metadata,
|
|
220
|
+
# )
|
|
221
|
+
|
|
222
|
+
# mock_service.return_value = service_data()
|
|
223
|
+
# with patch.object(ExecuteService, "execute", return_value=event if event else {"id": None}):
|
|
224
|
+
# backend = GoogleCalendarBackend()
|
|
225
|
+
# backend.update_external_activity(activity_no_metadata)
|
|
226
|
+
# backend.update_external_activity(activity_passed)
|
|
227
|
+
# backend.update_external_activity(activity)
|
|
228
|
+
# backend.update_external_activity(activity_with_parent)
|
|
229
|
+
|
|
230
|
+
# assert (
|
|
231
|
+
# mock_service.call_count == 5
|
|
232
|
+
# ) # rather than 4 because we call create_external_activity if no metadata
|
|
233
|
+
# assert activity_no_metadata.external_id == external_id
|
|
234
|
+
# assert activity_no_metadata.metadata == {"google_backend": {"event": event if event else {"id": None}}}
|
|
235
|
+
|
|
236
|
+
# @pytest.mark.parametrize("response_status", [*list(ActivityParticipant.ParticipationStatus)])
|
|
237
|
+
# def test_send_participant_response_external_activity(
|
|
238
|
+
# self,
|
|
239
|
+
# mock_user_email,
|
|
240
|
+
# mock_service,
|
|
241
|
+
# response_status,
|
|
242
|
+
# sync_past_activity,
|
|
243
|
+
# event,
|
|
244
|
+
# person_factory,
|
|
245
|
+
# activity_fixture,
|
|
246
|
+
# ):
|
|
247
|
+
# global_preferences_registry.manager()["wbactivity_sync__sync_past_activity"] = sync_past_activity
|
|
248
|
+
# activity = activity_fixture
|
|
249
|
+
# person = person_factory()
|
|
250
|
+
# activity.participants.add(person, activity.creator)
|
|
251
|
+
# activity.save()
|
|
252
|
+
# creator_participant = ActivityParticipant.objects.filter(
|
|
253
|
+
# activity=activity, participant=activity.creator
|
|
254
|
+
# ).first()
|
|
255
|
+
# mock_service.return_value = service_data()
|
|
256
|
+
# with patch.object(ExecuteService, "execute", return_value=event if event else {"id": None}) as mock_execute:
|
|
257
|
+
# backend = GoogleCalendarBackend()
|
|
258
|
+
# activityparticipant = activity.activity_participants.filter(participant=person).first()
|
|
259
|
+
# backend.send_participant_response_external_activity(activityparticipant, response_status)
|
|
260
|
+
# backend.send_participant_response_external_activity(creator_participant, response_status)
|
|
261
|
+
# if event:
|
|
262
|
+
# assert mock_execute.call_count
|
|
263
|
+
# else:
|
|
264
|
+
# assert mock_execute.call_count == 0
|
|
265
|
+
|
|
266
|
+
# @patch(
|
|
267
|
+
# "wbcrm.synchronization.activity.backends.google.google_calendar_backend.GoogleCalendarBackend.sync_with_external_calendar"
|
|
268
|
+
# )
|
|
269
|
+
# def test_sync_with_external_calendar(
|
|
270
|
+
# self, mock_handle_changes, mock_user_email, mock_service, sync_past_activity, event
|
|
271
|
+
# ):
|
|
272
|
+
# user = get_or_create_superuser()
|
|
273
|
+
# request = APIRequestFactory().get("", **{"HTTP_X-Goog-Channel-Id": user.id})
|
|
274
|
+
# backend = GoogleCalendarBackend()
|
|
275
|
+
# backend.sync_with_external_calendar(request)
|
|
276
|
+
# assert mock_handle_changes.call_count == 1
|
|
277
|
+
|
|
278
|
+
# def test_get_sync_token(self, mock_user_email, mock_service, sync_past_activity, event):
|
|
279
|
+
# user = get_or_create_superuser()
|
|
280
|
+
# user.metadata = {"google_backend": {"sync_token": "fake_token"}}
|
|
281
|
+
# user.save()
|
|
282
|
+
# backend = GoogleCalendarBackend()
|
|
283
|
+
# assert backend.get_sync_token(user) == "fake_token"
|
|
284
|
+
|
|
285
|
+
# def test_get_external_activity(self, mock_user_email, mock_service, sync_past_activity, event):
|
|
286
|
+
# pass
|
|
287
|
+
|
|
288
|
+
# def test_forward_external_activity(self, mock_user_email, mock_service, sync_past_activity, event):
|
|
289
|
+
# pass
|
|
290
|
+
|
|
291
|
+
# @patch(
|
|
292
|
+
# "wbcrm.synchronization.activity.backends.google.google_calendar_backend.GoogleCalendarBackend._get_service_account_url"
|
|
293
|
+
# )
|
|
294
|
+
# def test_set_web_hook(self, mock_url, mock_user_email, mock_service, sync_past_activity, event):
|
|
295
|
+
# user = get_or_create_superuser()
|
|
296
|
+
# watch = {"id": "fake_id"}
|
|
297
|
+
# mock_service.return_value = service_data()
|
|
298
|
+
# with patch.object(ExecuteService, "execute", return_value=watch):
|
|
299
|
+
# GoogleCalendarBackend().set_web_hook(user)
|
|
300
|
+
# assert user.metadata["google_backend"]["watch"] == watch
|
|
301
|
+
|
|
302
|
+
# def test_stop_web_hook(self, mock_user_email, mock_service, sync_past_activity, event):
|
|
303
|
+
# user = get_or_create_superuser()
|
|
304
|
+
# user.metadata = {"google_backend": {"watch": {"id": "fake_id", "resourceId": "fake_resource_id"}}}
|
|
305
|
+
# user.save()
|
|
306
|
+
# watch = {"id": "fake_id"}
|
|
307
|
+
# mock_service.return_value = service_data()
|
|
308
|
+
# with patch.object(ExecuteService, "execute", return_value=watch):
|
|
309
|
+
# GoogleCalendarBackend().stop_web_hook(user)
|
|
310
|
+
# assert user.metadata["google_backend"] == {}
|
|
311
|
+
|
|
312
|
+
# def test_check_web_hook(self, mock_user_email, mock_service, sync_past_activity, event):
|
|
313
|
+
# tomorrow = (timezone.now() + datetime.timedelta(days=1)).replace(tzinfo=None)
|
|
314
|
+
# user = get_or_create_superuser()
|
|
315
|
+
# user.metadata = {"google_backend": {"watch": {"expiration": datetime.datetime.timestamp(tomorrow) * 1000}}}
|
|
316
|
+
# user.save()
|
|
317
|
+
# with pytest.warns() as record:
|
|
318
|
+
# GoogleCalendarBackend().check_web_hook(user)
|
|
319
|
+
# assert len(record) == 1
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
# import datetime
|
|
2
|
+
# from zoneinfo import ZoneInfo
|
|
3
|
+
|
|
4
|
+
# import pytest
|
|
5
|
+
# from django.conf import settings
|
|
6
|
+
# from dynamic_preferences.registries import global_preferences_registry
|
|
7
|
+
# from wbcrm.models import (
|
|
8
|
+
# Activity,
|
|
9
|
+
# ActivityParticipant,
|
|
10
|
+
# CalendarItem,
|
|
11
|
+
# EmailContact,
|
|
12
|
+
# Person,
|
|
13
|
+
# )
|
|
14
|
+
|
|
15
|
+
# from ..utils import GoogleSyncUtils
|
|
16
|
+
# from .test_data import event, event_list
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
# @pytest.mark.django_db
|
|
20
|
+
# class TestUtils:
|
|
21
|
+
# def test_add_instance_metadata(self, activity_factory):
|
|
22
|
+
# new_metadata = {"google_backend": {"instance": {"uID": "UID"}, "event": {"id": "event id"}}}
|
|
23
|
+
# parent_occurrence: Activity = activity_factory(
|
|
24
|
+
# metadata={"google_backend": {"instance": {"originalStartTime": {"dateTime": "Fake Date Time"}}}}
|
|
25
|
+
# )
|
|
26
|
+
# child_activity_a: Activity = activity_factory(
|
|
27
|
+
# parent_occurrence=parent_occurrence,
|
|
28
|
+
# metadata={"google_backend": {"instance": {"originalStartTime": {"dateTime": "Fake Date Time A"}}}},
|
|
29
|
+
# )
|
|
30
|
+
# child_activity_b: Activity = activity_factory(
|
|
31
|
+
# parent_occurrence=parent_occurrence,
|
|
32
|
+
# metadata={"google_backend": {"instance": {"originalStartTime": {"dateTime": "Fake Date Time B"}}}},
|
|
33
|
+
# )
|
|
34
|
+
# child_activity_c: Activity = activity_factory(
|
|
35
|
+
# parent_occurrence=parent_occurrence,
|
|
36
|
+
# metadata={"google_backend": {"instance": {"originalStartTime": {"dateTime": "Fake Date Time C"}}}},
|
|
37
|
+
# )
|
|
38
|
+
# GoogleSyncUtils.add_instance_metadata(parent_occurrence, event_list, new_metadata)
|
|
39
|
+
# parent_occurrence = Activity.objects.get(id=parent_occurrence.id)
|
|
40
|
+
# child_activity_a = Activity.objects.get(id=child_activity_a.id)
|
|
41
|
+
# child_activity_b = Activity.objects.get(id=child_activity_b.id)
|
|
42
|
+
# child_activity_c = Activity.objects.get(id=child_activity_c.id)
|
|
43
|
+
# assert parent_occurrence.metadata["google_backend"]["instance"]["metaTest"] == "Parent"
|
|
44
|
+
# assert child_activity_a.external_id == "2"
|
|
45
|
+
# assert child_activity_a.metadata["google_backend"]["instance"]["metaTest"] == "Child A"
|
|
46
|
+
# assert child_activity_b.external_id == "3"
|
|
47
|
+
# assert child_activity_b.metadata["google_backend"]["instance"]["metaTest"] == "Child B"
|
|
48
|
+
# assert child_activity_c.external_id == "4"
|
|
49
|
+
# assert child_activity_c.metadata["google_backend"]["instance"]["metaTest"] == "Child C"
|
|
50
|
+
|
|
51
|
+
# def test_convert_activity_visibility_to_event_visibility(self):
|
|
52
|
+
# assert (
|
|
53
|
+
# GoogleSyncUtils.convert_activity_visibility_to_event_visibility(CalendarItem.Visibility.PUBLIC) == "public"
|
|
54
|
+
# )
|
|
55
|
+
# assert (
|
|
56
|
+
# GoogleSyncUtils.convert_activity_visibility_to_event_visibility(CalendarItem.Visibility.PRIVATE)
|
|
57
|
+
# == "private"
|
|
58
|
+
# )
|
|
59
|
+
# assert (
|
|
60
|
+
# GoogleSyncUtils.convert_activity_visibility_to_event_visibility(CalendarItem.Visibility.CONFIDENTIAL)
|
|
61
|
+
# == "private"
|
|
62
|
+
# )
|
|
63
|
+
|
|
64
|
+
# def test_convert_event_visibility_to_activity_visibility(self):
|
|
65
|
+
# assert (
|
|
66
|
+
# GoogleSyncUtils.convert_event_visibility_to_activity_visibility("private")
|
|
67
|
+
# == CalendarItem.Visibility.PRIVATE
|
|
68
|
+
# ) or (
|
|
69
|
+
# GoogleSyncUtils.convert_event_visibility_to_activity_visibility("private")
|
|
70
|
+
# == CalendarItem.Visibility.CONFIDENTIAL
|
|
71
|
+
# )
|
|
72
|
+
# assert (
|
|
73
|
+
# GoogleSyncUtils.convert_event_visibility_to_activity_visibility("public") == CalendarItem.Visibility.PUBLIC
|
|
74
|
+
# )
|
|
75
|
+
|
|
76
|
+
# def test_convert_attendee_status_to_participant_status(self):
|
|
77
|
+
# assert (
|
|
78
|
+
# GoogleSyncUtils.convert_attendee_status_to_participant_status("accepted")
|
|
79
|
+
# == ActivityParticipant.ParticipationStatus.ATTENDS
|
|
80
|
+
# )
|
|
81
|
+
# assert (
|
|
82
|
+
# GoogleSyncUtils.convert_attendee_status_to_participant_status("declined")
|
|
83
|
+
# == ActivityParticipant.ParticipationStatus.CANCELLED
|
|
84
|
+
# )
|
|
85
|
+
# assert (
|
|
86
|
+
# GoogleSyncUtils.convert_attendee_status_to_participant_status("tentative")
|
|
87
|
+
# == ActivityParticipant.ParticipationStatus.MAYBE
|
|
88
|
+
# )
|
|
89
|
+
# assert (
|
|
90
|
+
# GoogleSyncUtils.convert_attendee_status_to_participant_status("Something different")
|
|
91
|
+
# == ActivityParticipant.ParticipationStatus.NOTRESPONDED
|
|
92
|
+
# )
|
|
93
|
+
|
|
94
|
+
# def test_convert_participant_status_to_attendee_status(self):
|
|
95
|
+
# assert (
|
|
96
|
+
# GoogleSyncUtils.convert_participant_status_to_attendee_status(
|
|
97
|
+
# ActivityParticipant.ParticipationStatus.ATTENDS
|
|
98
|
+
# )
|
|
99
|
+
# == "accepted"
|
|
100
|
+
# )
|
|
101
|
+
# assert (
|
|
102
|
+
# GoogleSyncUtils.convert_participant_status_to_attendee_status(
|
|
103
|
+
# ActivityParticipant.ParticipationStatus.ATTENDS_DIGITALLY
|
|
104
|
+
# )
|
|
105
|
+
# == "accepted"
|
|
106
|
+
# )
|
|
107
|
+
# assert (
|
|
108
|
+
# GoogleSyncUtils.convert_participant_status_to_attendee_status(
|
|
109
|
+
# ActivityParticipant.ParticipationStatus.CANCELLED
|
|
110
|
+
# )
|
|
111
|
+
# == "declined"
|
|
112
|
+
# )
|
|
113
|
+
# assert (
|
|
114
|
+
# GoogleSyncUtils.convert_participant_status_to_attendee_status(
|
|
115
|
+
# ActivityParticipant.ParticipationStatus.MAYBE
|
|
116
|
+
# )
|
|
117
|
+
# == "tentative"
|
|
118
|
+
# )
|
|
119
|
+
# assert GoogleSyncUtils.convert_participant_status_to_attendee_status("Something different") == "notResponded"
|
|
120
|
+
|
|
121
|
+
# @pytest.mark.parametrize("google_event", [{}, event])
|
|
122
|
+
# def test_get_participants(self, google_event, person_factory, email_contact_factory):
|
|
123
|
+
# person_a = person_factory()
|
|
124
|
+
# person_b = person_factory()
|
|
125
|
+
# person_c = person_factory()
|
|
126
|
+
# email_contact_factory(primary=True, entry=person_a, address="Foo@Foo.com")
|
|
127
|
+
# email_contact_factory(primary=True, entry=person_b, address="Bar@Bar.com")
|
|
128
|
+
# part_list = GoogleSyncUtils.get_or_create_participants(google_event, person_c)
|
|
129
|
+
# if not google_event:
|
|
130
|
+
# assert part_list == [{"person_id": person_c.id, "status": ActivityParticipant.ParticipationStatus.ATTENDS}]
|
|
131
|
+
# else:
|
|
132
|
+
# person_d = Person.objects.get(last_name="Foo Bar")
|
|
133
|
+
# person_e = Person.objects.get(last_name="Bar@Foo.com")
|
|
134
|
+
# assert len(part_list) == 5
|
|
135
|
+
# assert {"person_id": person_a.id, "status": ActivityParticipant.ParticipationStatus.ATTENDS} in part_list
|
|
136
|
+
# assert {"person_id": person_b.id, "status": ActivityParticipant.ParticipationStatus.CANCELLED} in part_list
|
|
137
|
+
# assert {"person_id": person_c.id, "status": ActivityParticipant.ParticipationStatus.ATTENDS} in part_list
|
|
138
|
+
# assert {"person_id": person_d.id, "status": ActivityParticipant.ParticipationStatus.MAYBE} in part_list
|
|
139
|
+
# assert {"person_id": person_e.id, "status": ActivityParticipant.ParticipationStatus.MAYBE} in part_list
|
|
140
|
+
|
|
141
|
+
# @pytest.mark.parametrize("can_sync", [False, True])
|
|
142
|
+
# @pytest.mark.parametrize("google_event", [{}, event])
|
|
143
|
+
# def test_convert_activity_participants_to_attendees_list(
|
|
144
|
+
# self, can_sync, google_event, activity_factory, person_factory, internal_user_factory, email_contact_factory
|
|
145
|
+
# ):
|
|
146
|
+
# global_preferences_registry.manager()["wbactivity_sync__sync_external_participants"] = can_sync
|
|
147
|
+
# person_a: Person = internal_user_factory()
|
|
148
|
+
# person_b: Person = person_factory()
|
|
149
|
+
# person_c: Person = person_factory()
|
|
150
|
+
# email_contact_factory(primary=True, entry=person_a, address="A@A.com")
|
|
151
|
+
# email_contact_factory(primary=True, entry=person_b, address="B@B.com")
|
|
152
|
+
# email_contact_factory(primary=True, entry=person_c, address="Foo@Bar.com")
|
|
153
|
+
# activity: Activity = activity_factory(creator=person_a, participants=[person_a.id, person_b.id, person_c])
|
|
154
|
+
# # attendees: list[dict] = convert_activity_participants_to_attendees_list(activity, google_event)
|
|
155
|
+
# attendees: list[dict] = GoogleSyncUtils.convert_activity_participants_to_attendees(activity, google_event)
|
|
156
|
+
|
|
157
|
+
# person_a_dict: dict = {
|
|
158
|
+
# "displayName": person_a.computed_str,
|
|
159
|
+
# "email": str(person_a.primary_email_contact()),
|
|
160
|
+
# "responseStatus": "accepted",
|
|
161
|
+
# }
|
|
162
|
+
# person_b_dict: dict = {
|
|
163
|
+
# "displayName": person_b.computed_str,
|
|
164
|
+
# "email": str(person_b.primary_email_contact()),
|
|
165
|
+
# "responseStatus": "needsAction",
|
|
166
|
+
# }
|
|
167
|
+
# person_c_dict: dict = {
|
|
168
|
+
# "displayName": person_c.computed_str,
|
|
169
|
+
# "email": str(person_c.primary_email_contact()),
|
|
170
|
+
# "responseStatus": "needsAction",
|
|
171
|
+
# }
|
|
172
|
+
# if not google_event and not can_sync:
|
|
173
|
+
# assert len(attendees) == 1
|
|
174
|
+
# assert person_a_dict in attendees
|
|
175
|
+
# elif not google_event and can_sync:
|
|
176
|
+
# assert len(attendees) == 3
|
|
177
|
+
# assert person_a_dict in attendees
|
|
178
|
+
# assert person_b_dict in attendees
|
|
179
|
+
# elif google_event and not can_sync:
|
|
180
|
+
# assert len(attendees) == 2
|
|
181
|
+
# assert person_a_dict in attendees
|
|
182
|
+
# assert person_c_dict in attendees
|
|
183
|
+
# assert person_b_dict not in attendees
|
|
184
|
+
# else:
|
|
185
|
+
# assert len(attendees) == 3
|
|
186
|
+
# assert person_a_dict in attendees
|
|
187
|
+
# assert person_b_dict in attendees
|
|
188
|
+
# assert person_c_dict in attendees
|
|
189
|
+
|
|
190
|
+
# @pytest.mark.parametrize("created", [False])
|
|
191
|
+
# @pytest.mark.parametrize(
|
|
192
|
+
# "metadata",
|
|
193
|
+
# [{}, {"recurrence": ["Recurrence A"], "google_backend": {"event": {"recurrence": ["Recurrence B"]}}}],
|
|
194
|
+
# )
|
|
195
|
+
# def test_convert_activity_to_event(
|
|
196
|
+
# self, internal_user_factory, activity_factory, email_contact_factory, created, metadata
|
|
197
|
+
# ):
|
|
198
|
+
# timezone = ZoneInfo(settings.TIME_ZONE)
|
|
199
|
+
# person_a: Person = internal_user_factory()
|
|
200
|
+
# person_b: Person = internal_user_factory()
|
|
201
|
+
# email_contact_factory(primary=True, entry=person_a, address="Foo@Foo.com")
|
|
202
|
+
# email_contact_factory(primary=True, entry=person_b, address="Bar@Bar.com")
|
|
203
|
+
# activity: Activity = activity_factory(
|
|
204
|
+
# creator=person_a,
|
|
205
|
+
# participants=[person_b.id],
|
|
206
|
+
# visibility=CalendarItem.Visibility.PUBLIC,
|
|
207
|
+
# metadata=metadata,
|
|
208
|
+
# )
|
|
209
|
+
# event = GoogleSyncUtils.convert_activity_to_event(activity, created)
|
|
210
|
+
# assert event["summary"] == activity.title
|
|
211
|
+
# assert event["creator"] == str(activity.creator.primary_email_contact())
|
|
212
|
+
# assert event["organizer"] == str(activity.assigned_to.primary_email_contact())
|
|
213
|
+
# assert event["location"] == activity.location
|
|
214
|
+
# assert event["visibility"] == "public"
|
|
215
|
+
# assert event["attendees"] == [
|
|
216
|
+
# {
|
|
217
|
+
# "displayName": person_b.computed_str,
|
|
218
|
+
# "email": str(person_b.primary_email_contact()),
|
|
219
|
+
# "responseStatus": "needsAction",
|
|
220
|
+
# }
|
|
221
|
+
# ]
|
|
222
|
+
# assert event["start"] == {
|
|
223
|
+
# "dateTime": activity.period.lower.astimezone(timezone).isoformat(),
|
|
224
|
+
# "timeZone": settings.TIME_ZONE,
|
|
225
|
+
# }
|
|
226
|
+
# assert event["end"] == {
|
|
227
|
+
# "dateTime": activity.period.upper.astimezone(timezone).isoformat(),
|
|
228
|
+
# "timeZone": settings.TIME_ZONE,
|
|
229
|
+
# }
|
|
230
|
+
# if metadata and not created:
|
|
231
|
+
# assert event["recurrence"] == ["Recurrence B"]
|
|
232
|
+
# elif metadata and created:
|
|
233
|
+
# assert event["recurrence"] == ["Recurrence A"]
|
|
234
|
+
# else:
|
|
235
|
+
# assert event["recurrence"] == []
|
|
236
|
+
|
|
237
|
+
# def test_get_start_and_end(self):
|
|
238
|
+
# meta = {
|
|
239
|
+
# "start": {"dateTime": "2022-12-20T11:30:00+01:00", "timeZone": "Europe/Berlin"},
|
|
240
|
+
# "end": {"dateTime": "2022-12-20T12:30:00+01:00", "timeZone": "Europe/Berlin"},
|
|
241
|
+
# }
|
|
242
|
+
# meta_date = {
|
|
243
|
+
# "start": {"date": "2022-12-24"},
|
|
244
|
+
# "end": {"date": "2022-12-25"},
|
|
245
|
+
# }
|
|
246
|
+
# start, end = GoogleSyncUtils.get_start_and_end(meta)
|
|
247
|
+
# assert start == datetime.datetime(
|
|
248
|
+
# 2022, 12, 20, 11, 30, tzinfo=datetime.timezone(datetime.timedelta(seconds=3600))
|
|
249
|
+
# )
|
|
250
|
+
# assert end == datetime.datetime(
|
|
251
|
+
# 2022, 12, 20, 12, 30, tzinfo=datetime.timezone(datetime.timedelta(seconds=3600))
|
|
252
|
+
# )
|
|
253
|
+
# start, end = GoogleSyncUtils.get_start_and_end(meta_date)
|
|
254
|
+
# assert start == datetime.datetime(2022, 12, 24)
|
|
255
|
+
# assert end == datetime.datetime(2022, 12, 24, 23, 59, 59)
|
|
256
|
+
|
|
257
|
+
# @pytest.mark.parametrize(
|
|
258
|
+
# "organizer",
|
|
259
|
+
# ["", "Foo@Foo.com", "Bar@Bar.com"],
|
|
260
|
+
# )
|
|
261
|
+
# def test_get_person(self, person_factory, email_contact_factory, organizer):
|
|
262
|
+
# person_a: Person = person_factory()
|
|
263
|
+
# email_contact_factory(primary=True, entry=person_a, address="foo@foo.com")
|
|
264
|
+
|
|
265
|
+
# if organizer == "Foo@Foo.com":
|
|
266
|
+
# assert GoogleSyncUtils.get_or_create_person(organizer) == person_a
|
|
267
|
+
# elif organizer and (mail := organizer) == "Bar@Bar.com":
|
|
268
|
+
# creator = GoogleSyncUtils.get_or_create_person(mail)
|
|
269
|
+
# person_b = Person.objects.get(last_name=mail)
|
|
270
|
+
# assert EmailContact.objects.filter(entry=creator, address=mail.lower(), primary=True).exists()
|
|
271
|
+
# assert creator.id == person_b.id
|
|
272
|
+
# assert creator.last_name == mail
|
|
273
|
+
# else:
|
|
274
|
+
# assert GoogleSyncUtils.get_or_create_person(organizer) is None
|