1. import datetime
    
  2. 
    
  3. from django.core.exceptions import ValidationError
    
  4. from django.forms import DurationField
    
  5. from django.test import SimpleTestCase
    
  6. from django.utils import translation
    
  7. from django.utils.duration import duration_string
    
  8. 
    
  9. from . import FormFieldAssertionsMixin
    
  10. 
    
  11. 
    
  12. class DurationFieldTest(FormFieldAssertionsMixin, SimpleTestCase):
    
  13.     def test_durationfield_clean(self):
    
  14.         f = DurationField()
    
  15.         self.assertEqual(datetime.timedelta(seconds=30), f.clean("30"))
    
  16.         self.assertEqual(datetime.timedelta(minutes=15, seconds=30), f.clean("15:30"))
    
  17.         self.assertEqual(
    
  18.             datetime.timedelta(hours=1, minutes=15, seconds=30), f.clean("1:15:30")
    
  19.         )
    
  20.         self.assertEqual(
    
  21.             datetime.timedelta(
    
  22.                 days=1, hours=1, minutes=15, seconds=30, milliseconds=300
    
  23.             ),
    
  24.             f.clean("1 1:15:30.3"),
    
  25.         )
    
  26.         self.assertEqual(
    
  27.             datetime.timedelta(0, 10800),
    
  28.             f.clean(datetime.timedelta(0, 10800)),
    
  29.         )
    
  30.         msg = "This field is required."
    
  31.         with self.assertRaisesMessage(ValidationError, msg):
    
  32.             f.clean("")
    
  33.         msg = "Enter a valid duration."
    
  34.         with self.assertRaisesMessage(ValidationError, msg):
    
  35.             f.clean("not_a_time")
    
  36.         with self.assertRaisesMessage(ValidationError, msg):
    
  37.             DurationField().clean("P3(3D")
    
  38. 
    
  39.     def test_durationfield_clean_not_required(self):
    
  40.         f = DurationField(required=False)
    
  41.         self.assertIsNone(f.clean(""))
    
  42. 
    
  43.     def test_overflow(self):
    
  44.         msg = "The number of days must be between {min_days} and {max_days}.".format(
    
  45.             min_days=datetime.timedelta.min.days,
    
  46.             max_days=datetime.timedelta.max.days,
    
  47.         )
    
  48.         f = DurationField()
    
  49.         with self.assertRaisesMessage(ValidationError, msg):
    
  50.             f.clean("1000000000 00:00:00")
    
  51.         with self.assertRaisesMessage(ValidationError, msg):
    
  52.             f.clean("-1000000000 00:00:00")
    
  53. 
    
  54.     def test_overflow_translation(self):
    
  55.         msg = "Le nombre de jours doit ĂȘtre entre {min_days} et {max_days}.".format(
    
  56.             min_days=datetime.timedelta.min.days,
    
  57.             max_days=datetime.timedelta.max.days,
    
  58.         )
    
  59.         with translation.override("fr"):
    
  60.             with self.assertRaisesMessage(ValidationError, msg):
    
  61.                 DurationField().clean("1000000000 00:00:00")
    
  62. 
    
  63.     def test_durationfield_render(self):
    
  64.         self.assertWidgetRendersTo(
    
  65.             DurationField(initial=datetime.timedelta(hours=1)),
    
  66.             '<input id="id_f" type="text" name="f" value="01:00:00" required>',
    
  67.         )
    
  68. 
    
  69.     def test_durationfield_integer_value(self):
    
  70.         f = DurationField()
    
  71.         self.assertEqual(datetime.timedelta(0, 10800), f.clean(10800))
    
  72. 
    
  73.     def test_durationfield_prepare_value(self):
    
  74.         field = DurationField()
    
  75.         td = datetime.timedelta(minutes=15, seconds=30)
    
  76.         self.assertEqual(field.prepare_value(td), duration_string(td))
    
  77.         self.assertEqual(field.prepare_value("arbitrary"), "arbitrary")
    
  78.         self.assertIsNone(field.prepare_value(None))