|
7 | 7 | from django.test import TestCase
|
8 | 8 |
|
9 | 9 | from appointment.settings import APP_TIME_ZONE
|
10 |
| -from appointment.utils.date_time import convert_12_hour_time_to_24_hour_time, convert_minutes_in_human_readable_format, \ |
11 |
| - convert_str_to_date, convert_str_to_time, get_ar_end_time, get_current_year, get_timestamp, get_timezone, \ |
12 |
| - get_weekday_num, time_difference |
| 10 | +from appointment.utils.date_time import ( |
| 11 | + combine_date_and_time, convert_12_hour_time_to_24_hour_time, convert_24_hour_time_to_12_hour_time, |
| 12 | + convert_minutes_in_human_readable_format, convert_str_to_date, |
| 13 | + convert_str_to_time, get_ar_end_time, get_current_year, get_timestamp, get_timezone, get_weekday_num, |
| 14 | + time_difference |
| 15 | +) |
13 | 16 |
|
14 | 17 |
|
15 | 18 | class Convert12HourTo24HourTimeTests(TestCase):
|
@@ -66,6 +69,50 @@ def test_invalid_inputs(self):
|
66 | 69 | convert_12_hour_time_to_24_hour_time("01:60 AM")
|
67 | 70 |
|
68 | 71 |
|
| 72 | +class Convert24HourTimeTo12HourTimeTests(TestCase): |
| 73 | + |
| 74 | + def test_valid_24_hour_time_strings(self): |
| 75 | + self.assertEqual(convert_24_hour_time_to_12_hour_time("13:00"), "01:00 PM") |
| 76 | + self.assertEqual(convert_24_hour_time_to_12_hour_time("00:00"), "12:00 AM") |
| 77 | + self.assertEqual(convert_24_hour_time_to_12_hour_time("23:59"), "11:59 PM") |
| 78 | + self.assertEqual(convert_24_hour_time_to_12_hour_time("12:00"), "12:00 PM") |
| 79 | + self.assertEqual(convert_24_hour_time_to_12_hour_time("01:00"), "01:00 AM") |
| 80 | + |
| 81 | + def test_valid_24_hour_time_with_seconds(self): |
| 82 | + self.assertEqual(convert_24_hour_time_to_12_hour_time("13:00:01"), "01:00:01 PM") |
| 83 | + self.assertEqual(convert_24_hour_time_to_12_hour_time("00:00:59"), "12:00:59 AM") |
| 84 | + |
| 85 | + def test_datetime_time_object_input(self): |
| 86 | + time_input = datetime.time(13, 15) |
| 87 | + self.assertEqual(convert_24_hour_time_to_12_hour_time(time_input), "01:15 PM") |
| 88 | + time_input = datetime.time(0, 0) |
| 89 | + self.assertEqual(convert_24_hour_time_to_12_hour_time(time_input), "12:00 AM") |
| 90 | + |
| 91 | + def test_invalid_time_strings(self): |
| 92 | + with self.assertRaises(ValueError): |
| 93 | + convert_24_hour_time_to_12_hour_time("25:00") |
| 94 | + with self.assertRaises(ValueError): |
| 95 | + convert_24_hour_time_to_12_hour_time("-01:00") |
| 96 | + with self.assertRaises(ValueError): |
| 97 | + convert_24_hour_time_to_12_hour_time("13:60") |
| 98 | + with self.assertRaises(ValueError): |
| 99 | + convert_24_hour_time_to_12_hour_time("invalid") |
| 100 | + |
| 101 | + def test_incorrect_format(self): |
| 102 | + with self.assertRaises(ValueError): |
| 103 | + convert_24_hour_time_to_12_hour_time("1 PM") |
| 104 | + with self.assertRaises(ValueError): |
| 105 | + convert_24_hour_time_to_12_hour_time("13 PM") |
| 106 | + with self.assertRaises(ValueError): |
| 107 | + convert_24_hour_time_to_12_hour_time("24:00") |
| 108 | + |
| 109 | + def test_edge_cases(self): |
| 110 | + self.assertEqual(convert_24_hour_time_to_12_hour_time("12:00"), "12:00 PM") |
| 111 | + self.assertEqual(convert_24_hour_time_to_12_hour_time("00:00"), "12:00 AM") |
| 112 | + self.assertEqual(convert_24_hour_time_to_12_hour_time("11:59"), "11:59 AM") |
| 113 | + self.assertEqual(convert_24_hour_time_to_12_hour_time("23:59"), "11:59 PM") |
| 114 | + |
| 115 | + |
69 | 116 | class ConvertMinutesInHumanReadableFormatTests(TestCase):
|
70 | 117 | def test_valid_basic_conversions(self):
|
71 | 118 | """Test basic conversions"""
|
@@ -218,6 +265,15 @@ def test_end_time_past_midnight(self):
|
218 | 265 | # hence "23:30:00" + 60 minutes = "00:30:00".
|
219 | 266 | self.assertEqual(get_ar_end_time("23:30:00", 60), datetime.time(0, 30))
|
220 | 267 |
|
| 268 | + def test_invalid_start_time_type(self): |
| 269 | + """Test that an invalid start_time type raises a TypeError.""" |
| 270 | + with self.assertRaises(TypeError): |
| 271 | + get_ar_end_time([], 60) # Passing a list instead of a datetime.time object or string |
| 272 | + with self.assertRaises(TypeError): |
| 273 | + get_ar_end_time(12345, 30) # Passing an integer |
| 274 | + with self.assertRaises(TypeError): |
| 275 | + get_ar_end_time(None, 30) # Passing None |
| 276 | + |
221 | 277 |
|
222 | 278 | class TimeDifferenceTests(TestCase):
|
223 | 279 |
|
@@ -249,6 +305,66 @@ def test_negative_difference_with_datetime_objects(self):
|
249 | 305 | with self.assertRaises(ValueError):
|
250 | 306 | time_difference(datetime2, datetime1)
|
251 | 307 |
|
| 308 | + def test_mismatched_input_types(self): |
| 309 | + """Test that providing one 'datetime.time' and one datetime.datetime raises a ValueError.""" |
| 310 | + time_obj = datetime.time(10, 0) |
| 311 | + datetime_obj = datetime.datetime(2023, 1, 1, 11, 0) |
| 312 | + |
| 313 | + with self.assertRaises(ValueError) as context: |
| 314 | + time_difference(time_obj, datetime_obj) |
| 315 | + |
| 316 | + self.assertEqual(str(context.exception), |
| 317 | + "Both inputs should be of the same type, either datetime.time or datetime.datetime") |
| 318 | + |
| 319 | + # Test the reverse case as well for completeness |
| 320 | + with self.assertRaises(ValueError) as context: |
| 321 | + time_difference(datetime_obj, time_obj) |
| 322 | + |
| 323 | + self.assertEqual(str(context.exception), |
| 324 | + "Both inputs should be of the same type, either datetime.time or datetime.datetime") |
| 325 | + |
| 326 | + |
| 327 | +class CombineDateAndTimeTests(TestCase): |
| 328 | + def test_combine_valid_date_and_time(self): |
| 329 | + """Test combining a valid date and time.""" |
| 330 | + date = datetime.date(2023, 1, 1) |
| 331 | + time = datetime.time(12, 30) |
| 332 | + expected_datetime = datetime.datetime(2023, 1, 1, 12, 30) |
| 333 | + result = combine_date_and_time(date, time) |
| 334 | + self.assertEqual(result, expected_datetime) |
| 335 | + |
| 336 | + def test_combine_with_midnight(self): |
| 337 | + """Test combining a date with a midnight time.""" |
| 338 | + date = datetime.date(2023, 1, 1) |
| 339 | + time = datetime.time(0, 0) |
| 340 | + expected_datetime = datetime.datetime(2023, 1, 1, 0, 0) |
| 341 | + result = combine_date_and_time(date, time) |
| 342 | + self.assertEqual(result, expected_datetime) |
| 343 | + |
| 344 | + def test_combine_with_leap_year_date(self): |
| 345 | + """Test combining a leap year date and time.""" |
| 346 | + date = datetime.date(2024, 2, 29) |
| 347 | + time = datetime.time(23, 59) |
| 348 | + expected_datetime = datetime.datetime(2024, 2, 29, 23, 59) |
| 349 | + result = combine_date_and_time(date, time) |
| 350 | + self.assertEqual(result, expected_datetime) |
| 351 | + |
| 352 | + def test_combine_with_end_of_day(self): |
| 353 | + """Test combining a date with 'end of day time'.""" |
| 354 | + date = datetime.date(2023, 1, 1) |
| 355 | + time = datetime.time(23, 59, 59) |
| 356 | + expected_datetime = datetime.datetime(2023, 1, 1, 23, 59, 59) |
| 357 | + result = combine_date_and_time(date, time) |
| 358 | + self.assertEqual(result, expected_datetime) |
| 359 | + |
| 360 | + def test_combine_with_microseconds(self): |
| 361 | + """Test combining a date and time with microseconds.""" |
| 362 | + date = datetime.date(2023, 1, 1) |
| 363 | + time = datetime.time(12, 30, 15, 123456) |
| 364 | + expected_datetime = datetime.datetime(2023, 1, 1, 12, 30, 15, 123456) |
| 365 | + result = combine_date_and_time(date, time) |
| 366 | + self.assertEqual(result, expected_datetime) |
| 367 | + |
252 | 368 |
|
253 | 369 | class TimestampTests(TestCase):
|
254 | 370 | @patch('appointment.utils.date_time.timezone.now')
|
|
0 commit comments