django-model-utils/tests/test_fields/test_monitor_field.py
Maarten ter Huurne aeeb69a9dd Enable postponed evaluation of annotations for all test modules
This allows using the latest annotation syntax supported by the type
checker regardless of the runtime Python version.
2024-06-13 12:02:05 +02:00

129 lines
4.7 KiB
Python

from __future__ import annotations
from datetime import datetime, timezone
import time_machine
from django.test import TestCase
from model_utils.fields import MonitorField
from tests.models import DoubleMonitored, Monitored, MonitorWhen, MonitorWhenEmpty
class MonitorFieldTests(TestCase):
def setUp(self):
with time_machine.travel(datetime(2016, 1, 1, 10, 0, 0, tzinfo=timezone.utc)):
self.instance = Monitored(name='Charlie')
self.created = self.instance.name_changed
def test_save_no_change(self):
self.instance.save()
self.assertEqual(self.instance.name_changed, self.created)
def test_save_changed(self):
with time_machine.travel(datetime(2016, 1, 1, 12, 0, 0, tzinfo=timezone.utc)):
self.instance.name = 'Maria'
self.instance.save()
self.assertEqual(self.instance.name_changed, datetime(2016, 1, 1, 12, 0, 0, tzinfo=timezone.utc))
def test_double_save(self):
self.instance.name = 'Jose'
self.instance.save()
changed = self.instance.name_changed
self.instance.save()
self.assertEqual(self.instance.name_changed, changed)
def test_no_monitor_arg(self):
with self.assertRaises(TypeError):
MonitorField()
def test_monitor_default_is_none_when_nullable(self):
self.assertIsNone(self.instance.name_changed_nullable)
expected_datetime = datetime(2022, 1, 18, 12, 0, 0, tzinfo=timezone.utc)
self.instance.name = "Jose"
with time_machine.travel(expected_datetime, tick=False):
self.instance.save()
self.assertEqual(self.instance.name_changed_nullable, expected_datetime)
class MonitorWhenFieldTests(TestCase):
"""
Will record changes only when name is 'Jose' or 'Maria'
"""
def setUp(self):
with time_machine.travel(datetime(2016, 1, 1, 10, 0, 0, tzinfo=timezone.utc)):
self.instance = MonitorWhen(name='Charlie')
self.created = self.instance.name_changed
def test_save_no_change(self):
self.instance.save()
self.assertEqual(self.instance.name_changed, self.created)
def test_save_changed_to_Jose(self):
with time_machine.travel(datetime(2016, 1, 1, 12, 0, 0, tzinfo=timezone.utc)):
self.instance.name = 'Jose'
self.instance.save()
self.assertEqual(self.instance.name_changed, datetime(2016, 1, 1, 12, 0, 0, tzinfo=timezone.utc))
def test_save_changed_to_Maria(self):
with time_machine.travel(datetime(2016, 1, 1, 12, 0, 0, tzinfo=timezone.utc)):
self.instance.name = 'Maria'
self.instance.save()
self.assertEqual(self.instance.name_changed, datetime(2016, 1, 1, 12, 0, 0, tzinfo=timezone.utc))
def test_save_changed_to_Pedro(self):
self.instance.name = 'Pedro'
self.instance.save()
self.assertEqual(self.instance.name_changed, self.created)
def test_double_save(self):
self.instance.name = 'Jose'
self.instance.save()
changed = self.instance.name_changed
self.instance.save()
self.assertEqual(self.instance.name_changed, changed)
class MonitorWhenEmptyFieldTests(TestCase):
"""
Monitor should never be updated id when is an empty list.
"""
def setUp(self):
self.instance = MonitorWhenEmpty(name='Charlie')
self.created = self.instance.name_changed
def test_save_no_change(self):
self.instance.save()
self.assertEqual(self.instance.name_changed, self.created)
def test_save_changed_to_Jose(self):
self.instance.name = 'Jose'
self.instance.save()
self.assertEqual(self.instance.name_changed, self.created)
def test_save_changed_to_Maria(self):
self.instance.name = 'Maria'
self.instance.save()
self.assertEqual(self.instance.name_changed, self.created)
class MonitorDoubleFieldTests(TestCase):
def setUp(self):
DoubleMonitored.objects.create(name='Charlie', name2='Charlie2')
def test_recursion_error_with_only(self):
# Any field passed to only() is generating a recursion error
list(DoubleMonitored.objects.only('id'))
def test_recursion_error_with_defer(self):
# Only monitored fields passed to defer() are failing
list(DoubleMonitored.objects.defer('name'))
def test_monitor_still_works_with_deferred_fields_filtered_out_of_save_initial(self):
obj = DoubleMonitored.objects.defer('name').get(name='Charlie')
with time_machine.travel(datetime(2016, 12, 1, tzinfo=timezone.utc)):
obj.name = 'Charlie2'
obj.save()
self.assertEqual(obj.name_changed, datetime(2016, 12, 1, tzinfo=timezone.utc))