Skip to content

Commit

Permalink
Adjusted tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
charettes committed Jan 19, 2019
1 parent 92c2a2a commit ef1e239
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 32 deletions.
39 changes: 14 additions & 25 deletions sundial/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,32 +84,21 @@ def get_db_prep_value(self, value, connection, prepared=False):
if value is None or hasattr(value, 'resolve_expression'):
return value

if settings.USE_TZ:
if connection.features.supports_timezones:
# XXX: Investigate how to deal with PostgreSQL.
pass
elif timezone.is_aware(value):
value = timezone.make_naive(value, self.db_tzinfo)
else:
# Allow naive datetime to be provided and assume they are
# in db_timezone.
pass
else:
# If timezone support is turned off then it's assumed naive
# datetimes are passed in the expected timezone.
value = super(DateTimeField, self).get_db_prep_value(value, connection, prepared)
if (settings.USE_TZ and
not connection.features.supports_timezones and timezone.is_aware(value)):
return timezone.make_naive(value, self.db_tzinfo)

return value
return super(DateTimeField, self).get_db_prep_value(value, connection, prepared)

def from_db_value(self, value, expression, connection, context=None):
if settings.USE_TZ:
if connection.features.supports_timezones:
# XXX: Investigate how to deal with PostgreSQL.
pass
else:
# Strip the tzinfo because it will be returned in the
# connection's timezone.
value = timezone.make_aware(value.replace(tzinfo=None), self.db_tzinfo)
else:
value = super(DateTimeField, self).from_db_value(value, expression, connection)
if value is None:
return value

if settings.USE_TZ and not connection.features.supports_timezones:
# At this point the value will be in the connection's timezone
# even if it's actually stored using self.db_timezone.
# Strip the bogus timezone assignment, make it aware in the
# appropriate timezone, and convert it it back to UTC.
value = timezone.make_aware(value.replace(tzinfo=None), self.db_tzinfo).astimezone(timezone.utc)

return value
8 changes: 8 additions & 0 deletions tests/test_fields/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from django.conf import settings
from django.db import models
from django.utils.encoding import python_2_unicode_compatible

from sundial.fields import DateTimeField, TimezoneField

Expand All @@ -12,5 +13,12 @@ class TimezoneModel(models.Model):
null_timezone = TimezoneField(blank=True, null=True)


@python_2_unicode_compatible
class DbTimezoneModel(models.Model):
datetime = DateTimeField(db_timezone='Europe/Amsterdam')

class Meta:
ordering = ('pk',)

def __str__(self):
return str(self.datetime)
60 changes: 53 additions & 7 deletions tests/test_fields/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,17 @@ def test_choices_formfield(self):


class DateTimeFieldTests(TestCase):
naive_datetime = datetime(2018, 1, 1)
aware_datetime = timezone.make_aware(datetime(2018, 1, 1), pytz.timezone('Europe/Amsterdam'))

@classmethod
def setUpTestData(cls):
cls.naive_object = DbTimezoneModel.objects.create(datetime=cls.naive_datetime)
with override_settings(USE_TZ=True, TIME_ZONE='UTC'):
cls.utc_object = DbTimezoneModel.objects.create(datetime=cls.aware_datetime)
with override_settings(USE_TZ=True, TIME_ZONE='Europe/Paris'):
cls.paris_object = DbTimezoneModel.objects.create(datetime=cls.aware_datetime)

def assert_deconstruct_db_timezone(self, field, expected_db_timezone):
name, path, args, kwargs = field.deconstruct()
self.assertEqual(name, 'field')
Expand All @@ -98,10 +109,45 @@ def test_deconstruct(self):
field = DateTimeField(name='field', db_timezone='Europe/Amsterdam')
self.assert_deconstruct_db_timezone(field, 'Europe/Amsterdam')

@override_settings(USE_TZ=True, TIME_ZONE='UTC')
def test_database_roundtrip(self):
tzinfo = pytz.timezone('Europe/Amsterdam')
aware_datetime = timezone.make_aware(datetime(2018, 1, 1), tzinfo)
obj = DbTimezoneModel.objects.create(datetime=aware_datetime)
obj.refresh_from_db()
self.assertEqual(obj.datetime, aware_datetime)
def test_retreival(self):
self.naive_object.refresh_from_db()
self.assertEqual(self.naive_object.datetime, self.naive_datetime)
self.utc_object.refresh_from_db()
self.assertEqual(self.utc_object.datetime, self.naive_datetime)
with override_settings(USE_TZ=True, TIME_ZONE='UTC'):
utc = timezone.get_current_timezone()
self.naive_object.refresh_from_db()
self.assertEqual(self.naive_object.datetime, self.aware_datetime)
self.assertEqual(self.naive_object.datetime.tzinfo, utc)
self.utc_object.refresh_from_db()
self.assertEqual(self.utc_object.datetime, self.aware_datetime)
self.assertEqual(self.utc_object.datetime.tzinfo, utc)
self.paris_object.refresh_from_db()
self.assertEqual(self.paris_object.datetime, self.aware_datetime)
self.assertEqual(self.paris_object.datetime.tzinfo, utc)
with override_settings(USE_TZ=True, TIME_ZONE='Europe/Paris'):
self.naive_object.refresh_from_db()
self.assertEqual(self.naive_object.datetime, self.aware_datetime)
self.assertEqual(self.naive_object.datetime.tzinfo, utc)
self.utc_object.refresh_from_db()
self.assertEqual(self.utc_object.datetime, self.aware_datetime)
self.assertEqual(self.utc_object.datetime.tzinfo, utc)
self.paris_object.refresh_from_db()
self.assertEqual(self.paris_object.datetime, self.aware_datetime)
self.assertEqual(self.paris_object.datetime.tzinfo, utc)

def test_lookup(self):
self.assertSequenceEqual(
DbTimezoneModel.objects.filter(datetime=self.naive_datetime),
[self.naive_object, self.utc_object, self.paris_object],
)
with override_settings(USE_TZ=True, TIME_ZONE='UTC'):
self.assertSequenceEqual(
DbTimezoneModel.objects.filter(datetime=self.aware_datetime),
[self.naive_object, self.utc_object, self.paris_object],
)
with override_settings(USE_TZ=True, TIME_ZONE='Europe/Paris'):
self.assertSequenceEqual(
DbTimezoneModel.objects.filter(datetime=self.aware_datetime),
[self.naive_object, self.utc_object, self.paris_object],
)

0 comments on commit ef1e239

Please sign in to comment.