django-model-utils/tests/test_models/test_status_model.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

101 lines
4.1 KiB
Python

from __future__ import annotations
from datetime import datetime, timezone
import time_machine
from django.test.testcases import TestCase
from tests.models import CustomManagerStatusModel, Status, StatusPlainTuple
class StatusModelTests(TestCase):
def setUp(self):
self.model = Status
self.on_hold = Status.STATUS.on_hold
self.active = Status.STATUS.active
def test_created(self):
with time_machine.travel(datetime(2016, 1, 1)):
c1 = self.model.objects.create()
self.assertTrue(c1.status_changed, datetime(2016, 1, 1))
self.model.objects.create()
self.assertEqual(self.model.active.count(), 2)
self.assertEqual(self.model.deleted.count(), 0)
def test_modification(self):
t1 = self.model.objects.create()
date_created = t1.status_changed
t1.status = self.on_hold
t1.save()
self.assertEqual(self.model.active.count(), 0)
self.assertEqual(self.model.on_hold.count(), 1)
self.assertTrue(t1.status_changed > date_created)
date_changed = t1.status_changed
t1.save()
self.assertEqual(t1.status_changed, date_changed)
date_active_again = t1.status_changed
t1.status = self.active
t1.save()
self.assertTrue(t1.status_changed > date_active_again)
def test_save_with_update_fields_overrides_status_changed_provided(self):
'''
Tests if the save method updated status_changed field
accordingly when update_fields is used as an argument
and status_changed is provided
'''
with time_machine.travel(datetime(2020, 1, 1, tzinfo=timezone.utc)):
t1 = Status.objects.create()
with time_machine.travel(datetime(2020, 1, 2, tzinfo=timezone.utc)):
t1.status = Status.on_hold
t1.save(update_fields=['status', 'status_changed'])
self.assertEqual(t1.status_changed, datetime(2020, 1, 2, tzinfo=timezone.utc))
def test_save_with_update_fields_overrides_status_changed_not_provided(self):
'''
Tests if the save method updated status_changed field
accordingly when update_fields is used as an argument
with status and status_changed is not provided
'''
with time_machine.travel(datetime(2020, 1, 1, tzinfo=timezone.utc)):
t1 = Status.objects.create()
with time_machine.travel(datetime(2020, 1, 2, tzinfo=timezone.utc)):
t1.status = Status.on_hold
t1.save(update_fields=['status'])
self.assertEqual(t1.status_changed, datetime(2020, 1, 2, tzinfo=timezone.utc))
class StatusModelPlainTupleTests(StatusModelTests):
def setUp(self):
self.model = StatusPlainTuple
self.on_hold = StatusPlainTuple.STATUS[2][0]
self.active = StatusPlainTuple.STATUS[0][0]
class StatusModelDefaultManagerTests(TestCase):
def test_default_manager_is_not_status_model_generated_ones(self):
# Regression test for GH-251
# The logic behind order for managers seems to have changed in Django 1.10
# and affects default manager.
# This code was previously failing because the first custom manager (which filters
# with first Choice value, here 'first_choice') generated by StatusModel was
# considered as default manager...
# This situation only happens when we define a model inheriting from an "abstract"
# class which defines an "objects" manager.
CustomManagerStatusModel.objects.create(status='first_choice')
CustomManagerStatusModel.objects.create(status='second_choice')
CustomManagerStatusModel.objects.create(status='second_choice')
# ...which made this count() equal to 1 (only 1 element with status='first_choice')...
self.assertEqual(CustomManagerStatusModel._default_manager.count(), 3)
# ...and this one equal to 0, because of 2 successive filters of 'first_choice'
# (default manager) and 'second_choice' (explicit filter below).
self.assertEqual(CustomManagerStatusModel._default_manager.filter(status='second_choice').count(), 2)