2
2
# Path: appointment/tests/utils/test_db_helpers.py
3
3
4
4
import datetime
5
+ from unittest import skip
5
6
from unittest .mock import MagicMock , PropertyMock , patch
6
7
7
8
from django .apps import apps
12
13
from django .test .client import RequestFactory
13
14
from django .urls import reverse
14
15
from django .utils import timezone
15
- from django_q .models import Schedule
16
16
17
+ from appointment .logger_config import get_logger
17
18
from appointment .models import Config , DayOff , PaymentInfo
18
19
from appointment .tests .base .base_test import BaseTest
19
20
from appointment .tests .mixins .base_mixin import ConfigMixin
31
32
staff_change_allowed_on_reschedule , update_appointment_reminder , username_in_user_model , working_hours_exist
32
33
)
33
34
35
+ logger = get_logger (__name__ )
36
+
37
+ # Check if django-q is installed
38
+ try :
39
+ from django_q .models import Schedule
40
+ from django_q .tasks import schedule
41
+
42
+ DJANGO_Q_AVAILABLE = True
43
+ except ImportError :
44
+ DJANGO_Q_AVAILABLE = False
45
+ Schedule = None
46
+ schedule = None
47
+
48
+
49
+ @skip ("Django-Q is not available" )
50
+ class DjangoQUnavailableTest (TestCase ):
51
+ def test_placeholder (self ):
52
+ self .skipTest ("Django-Q is not available" )
53
+
34
54
35
55
class TestCalculateSlots (TestCase ):
36
56
def setUp (self ):
@@ -165,18 +185,12 @@ def test_another_staff_member_no_day_off(self):
165
185
self .assertFalse (check_day_off_for_staff (self .staff_member2 , "2023-10-06" ))
166
186
167
187
168
- class TestCreateAndSaveAppointment (BaseTest ):
169
-
188
+ class TestCreateAndSaveAppointment (BaseTest , TestCase ):
170
189
def setUp (self ):
171
- super ().setUp () # Call the parent class setup
172
- # Specific setups for this test class
173
- self .ar = self .create_appt_request_for_sm1 ()
190
+ super ().setUp ()
174
191
self .factory = RequestFactory ()
175
192
self .request = self .factory .get ('/' )
176
-
177
- def tearDown (self ):
178
- Appointment .objects .all ().delete ()
179
- AppointmentRequest .objects .all ().delete ()
193
+ self .ar = self .create_appt_request_for_sm1 ()
180
194
181
195
def test_create_and_save_appointment (self ):
182
196
client_data = {
@@ -190,7 +204,8 @@ def test_create_and_save_appointment(self):
190
204
'additional_info' : 'Please bring a Zat gun.'
191
205
}
192
206
193
- appointment = create_and_save_appointment (self .ar , client_data , appointment_data , self .request )
207
+ with patch ('appointment.utils.db_helpers.schedule_email_reminder' ) as mock_schedule_reminder :
208
+ appointment = create_and_save_appointment (self .ar , client_data , appointment_data , self .request )
194
209
195
210
self .assertIsNotNone (appointment )
196
211
self .assertEqual (appointment .client .email , client_data ['email' ])
@@ -199,6 +214,32 @@ def test_create_and_save_appointment(self):
199
214
self .assertEqual (appointment .address , appointment_data ['address' ])
200
215
self .assertEqual (appointment .additional_info , appointment_data ['additional_info' ])
201
216
217
+ if DJANGO_Q_AVAILABLE :
218
+ mock_schedule_reminder .assert_called_once ()
219
+ else :
220
+ mock_schedule_reminder .assert_not_called ()
221
+
222
+ @patch ('appointment.utils.db_helpers.DJANGO_Q_AVAILABLE' , False )
223
+ def test_create_and_save_appointment_without_django_q (self ):
224
+ client_data = {
225
+
226
+ 'name' : 'samantha.carter' ,
227
+ }
228
+ appointment_data = {
229
+ 'phone' : '987654321' ,
230
+ 'want_reminder' : True ,
231
+ 'address' : '456, SGC, Colorado Springs, USA' ,
232
+ 'additional_info' : 'Bring naquadah generator.'
233
+ }
234
+
235
+ with patch ('appointment.utils.db_helpers.logger.warning' ) as mock_logger_warning :
236
+ appointment = create_and_save_appointment (self .ar , client_data , appointment_data , self .request )
237
+
238
+ self .assertIsNotNone (appointment )
239
+ self .assertEqual (appointment .client .email , client_data ['email' ])
240
+ mock_logger_warning .assert_called_with (
241
+ f"Email reminder requested for appointment { appointment .id } , but django-q is not available." )
242
+
202
243
203
244
def get_mock_reverse (url_name , ** kwargs ):
204
245
"""A mocked version of the reverse function."""
@@ -208,6 +249,13 @@ def get_mock_reverse(url_name, **kwargs):
208
249
209
250
210
251
class ScheduleEmailReminderTest (BaseTest ):
252
+ @classmethod
253
+ def setUpClass (cls ):
254
+ if not DJANGO_Q_AVAILABLE :
255
+ import unittest
256
+ raise unittest .SkipTest ("Django-Q is not available" )
257
+ super ().setUpClass ()
258
+
211
259
def setUp (self ):
212
260
super ().setUp ()
213
261
self .factory = RequestFactory ()
@@ -217,6 +265,7 @@ def setUp(self):
217
265
def tearDown (self ):
218
266
Appointment .objects .all ().delete ()
219
267
AppointmentRequest .objects .all ().delete ()
268
+ super ().tearDown ()
220
269
221
270
def test_schedule_email_reminder_cluster_running (self ):
222
271
with patch ('appointment.settings.check_q_cluster' , return_value = True ), \
@@ -233,7 +282,14 @@ def test_schedule_email_reminder_cluster_not_running(self):
233
282
"Django-Q cluster is not running. Email reminder will not be scheduled." )
234
283
235
284
236
- class UpdateAppointmentReminderTest (BaseTest ):
285
+ class UpdateAppointmentReminderTest (BaseTest , TestCase ):
286
+ @classmethod
287
+ def setUpClass (cls ):
288
+ if not DJANGO_Q_AVAILABLE :
289
+ import unittest
290
+ raise unittest .SkipTest ("Django-Q is not available" )
291
+ super ().setUpClass ()
292
+
237
293
def setUp (self ):
238
294
super ().setUp ()
239
295
self .factory = RequestFactory ()
@@ -243,6 +299,7 @@ def setUp(self):
243
299
def tearDown (self ):
244
300
Appointment .objects .all ().delete ()
245
301
AppointmentRequest .objects .all ().delete ()
302
+ super ().tearDown ()
246
303
247
304
def test_update_appointment_reminder_date_time_changed (self ):
248
305
appointment = self .create_appt_for_sm1 ()
@@ -267,7 +324,7 @@ def test_update_appointment_reminder_no_change(self):
267
324
mock_cancel_existing_reminder .assert_not_called ()
268
325
mock_schedule_email_reminder .assert_not_called ()
269
326
270
- @patch ('appointment.utils.db_helpers.logger' ) # Adjust the import path as necessary
327
+ @patch ('appointment.utils.db_helpers.logger' )
271
328
def test_reminder_not_scheduled_due_to_user_preference (self , mock_logger ):
272
329
# Scenario where user does not want a reminder
273
330
want_reminder = False
@@ -281,7 +338,7 @@ def test_reminder_not_scheduled_due_to_user_preference(self, mock_logger):
281
338
f"Reminder for appointment { self .appointment .id } is not scheduled per user's preference or past datetime."
282
339
)
283
340
284
- @patch ('appointment.utils.db_helpers.logger' ) # Adjust the import path as necessary
341
+ @patch ('appointment.utils.db_helpers.logger' )
285
342
def test_reminder_not_scheduled_due_to_past_datetime (self , mock_logger ):
286
343
# Scenario where the new datetime is in the past
287
344
want_reminder = True
@@ -371,6 +428,8 @@ def test_staff_change_not_allowed(self, mock_config_first):
371
428
372
429
class CancelExistingReminderTest (BaseTest ):
373
430
def test_cancel_existing_reminder (self ):
431
+ if not DJANGO_Q_AVAILABLE :
432
+ return
374
433
appointment = self .create_appt_for_sm1 ()
375
434
Schedule .objects .create (func = 'appointment.tasks.send_email_reminder' , name = f"reminder_{ appointment .id_request } " )
376
435
0 commit comments