Классы миксинов перенесены в проект
This commit is contained in:
@@ -11,4 +11,6 @@
|
||||
from .created_at_mixin_tests import CreatedAtMixinTests
|
||||
from .deleted_at_mixin_tests import DeletedAtMixinTests
|
||||
from .expired_at_mixin_tests import ExpiresAtMixinTests
|
||||
|
||||
from .slug_mixin_tests import SlugMixinTests
|
||||
from .updated_at_mixin_tests import UpdatedAtMixinTests
|
||||
from .uuid_id_mixin_tests import UuidIdMixinTests
|
||||
|
||||
59
net/xeaf/rack/tests/models/mixins/slug_mixin_tests.py
Normal file
59
net/xeaf/rack/tests/models/mixins/slug_mixin_tests.py
Normal file
@@ -0,0 +1,59 @@
|
||||
# DRF Rack
|
||||
# Библиотека классов расширений для Django REST Framework
|
||||
#
|
||||
# Автор: Николай В. Анохин <n.anokhin@xeaf.net>
|
||||
# Все права защищены. Лицензия: MIT
|
||||
|
||||
"""
|
||||
Описание класса SlugMixinTests
|
||||
"""
|
||||
|
||||
from django.db import connection
|
||||
from django.db import models
|
||||
from django.test import TransactionTestCase
|
||||
|
||||
from net.xeaf.rack.models.mixins import SlugMixin
|
||||
|
||||
|
||||
class SlugMixinTests(TransactionTestCase):
|
||||
"""
|
||||
Тесты для миксина SlugMixin
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
"""
|
||||
Создаем тестовую модель и таблицу для каждого теста
|
||||
"""
|
||||
|
||||
with connection.cursor() as cursor:
|
||||
cursor.execute('PRAGMA foreign_keys = OFF;')
|
||||
|
||||
class TestSlugModel(SlugMixin):
|
||||
name = models.CharField(max_length=100)
|
||||
|
||||
class Meta:
|
||||
app_label = 'test'
|
||||
db_table = 'test_slug_mixin'
|
||||
|
||||
self.TestModel = TestSlugModel
|
||||
|
||||
with connection.schema_editor() as editor:
|
||||
editor.create_model(TestSlugModel)
|
||||
|
||||
def tearDown(self):
|
||||
"""
|
||||
Удаляем таблицу после каждого теста
|
||||
"""
|
||||
|
||||
with connection.schema_editor() as editor:
|
||||
editor.delete_model(self.TestModel)
|
||||
|
||||
with connection.cursor() as cursor:
|
||||
cursor.execute('PRAGMA foreign_keys = ON;')
|
||||
|
||||
def test_slug_field_exists(self):
|
||||
"""
|
||||
Проверяем, что поле slug добавлено в модель
|
||||
"""
|
||||
|
||||
self.assertTrue(hasattr(self.TestModel, 'slug'))
|
||||
182
net/xeaf/rack/tests/models/mixins/updated_at_mixin_tests.py
Normal file
182
net/xeaf/rack/tests/models/mixins/updated_at_mixin_tests.py
Normal file
@@ -0,0 +1,182 @@
|
||||
# DRF Rack
|
||||
# Библиотека классов расширений для Django REST Framework
|
||||
#
|
||||
# Автор: Николай В. Анохин <n.anokhin@xeaf.net>
|
||||
# Все права защищены. Лицензия: MIT
|
||||
|
||||
"""
|
||||
Описание класса UpdatedAtMixinTests
|
||||
"""
|
||||
|
||||
import time
|
||||
from datetime import timedelta
|
||||
|
||||
from django.db import connection
|
||||
from django.db import models
|
||||
from django.test import TransactionTestCase
|
||||
from django.utils import timezone
|
||||
|
||||
from net.xeaf.rack.models.mixins import UpdatedAtMixin
|
||||
|
||||
|
||||
class UpdatedAtMixinTests(TransactionTestCase):
|
||||
"""
|
||||
Тесты для миксина UpdatedAtMixin
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
"""
|
||||
Создаем тестовую модель и таблицу для каждого теста
|
||||
"""
|
||||
|
||||
with connection.cursor() as cursor:
|
||||
cursor.execute('PRAGMA foreign_keys = OFF;')
|
||||
|
||||
class TestUpdatedAtModel(UpdatedAtMixin):
|
||||
name = models.CharField(max_length=100)
|
||||
|
||||
class Meta:
|
||||
app_label = 'test'
|
||||
db_table = 'test_updated_at_mixin'
|
||||
|
||||
self.TestModel = TestUpdatedAtModel
|
||||
|
||||
with connection.schema_editor() as editor:
|
||||
editor.create_model(TestUpdatedAtModel)
|
||||
|
||||
def tearDown(self):
|
||||
"""
|
||||
Удаляем таблицу после каждого теста
|
||||
"""
|
||||
|
||||
with connection.schema_editor() as editor:
|
||||
editor.delete_model(self.TestModel)
|
||||
|
||||
with connection.cursor() as cursor:
|
||||
cursor.execute('PRAGMA foreign_keys = ON;')
|
||||
|
||||
def test_updated_at_null_by_default(self):
|
||||
"""
|
||||
Проверяем, что при создании updated_at = None
|
||||
"""
|
||||
instance = self.TestModel.objects.create(name='Test Instance')
|
||||
self.assertIsNone(instance.updated_at)
|
||||
|
||||
def test_update_sets_current_time(self):
|
||||
"""
|
||||
Проверяем, что update() устанавливает текущее время
|
||||
"""
|
||||
|
||||
instance = self.TestModel.objects.create(name='Test Instance')
|
||||
before = timezone.now()
|
||||
|
||||
instance.update(save=False)
|
||||
|
||||
self.assertIsNotNone(instance.updated_at)
|
||||
self.assertGreaterEqual(instance.updated_at, before)
|
||||
self.assertLessEqual(instance.updated_at, timezone.now())
|
||||
|
||||
def test_update_saves_to_db_when_save_true(self):
|
||||
"""
|
||||
Проверяем, что update(save=True) сохраняет в БД
|
||||
"""
|
||||
|
||||
instance = self.TestModel.objects.create(name='Test Instance')
|
||||
instance.update(save=True)
|
||||
instance.refresh_from_db()
|
||||
|
||||
self.assertIsNotNone(instance.updated_at)
|
||||
|
||||
def test_update_does_not_save_when_save_false(self):
|
||||
"""
|
||||
Проверяем, что update(save=False) НЕ сохраняет в БД
|
||||
"""
|
||||
|
||||
instance = self.TestModel.objects.create(name='Test Instance')
|
||||
instance.update(save=False)
|
||||
instance.refresh_from_db()
|
||||
|
||||
self.assertIsNone(instance.updated_at)
|
||||
|
||||
def test_update_saves_by_default(self):
|
||||
"""
|
||||
Проверяем, что по умолчанию update() сохраняет в БД
|
||||
"""
|
||||
|
||||
instance = self.TestModel.objects.create(name='Test Instance')
|
||||
instance.update()
|
||||
instance.refresh_from_db()
|
||||
|
||||
self.assertIsNotNone(instance.updated_at)
|
||||
|
||||
def test_is_updated_returns_false_when_not_updated(self):
|
||||
"""
|
||||
Проверяем, что is_updated() возвращает False для новой записи
|
||||
"""
|
||||
|
||||
instance = self.TestModel.objects.create(name='Test Instance')
|
||||
self.assertFalse(instance.is_updated())
|
||||
|
||||
def test_is_updated_returns_true_when_updated(self):
|
||||
"""
|
||||
Проверяем, что is_updated() возвращает True после update()
|
||||
"""
|
||||
|
||||
instance = self.TestModel.objects.create(name='Test Instance')
|
||||
instance.update(save=False)
|
||||
self.assertTrue(instance.is_updated())
|
||||
|
||||
def test_is_updated_since_returns_false_when_not_updated(self):
|
||||
"""
|
||||
Проверяем, что is_updated_since() возвращает False для новой записи
|
||||
"""
|
||||
|
||||
instance = self.TestModel.objects.create(name='Test Instance')
|
||||
dt = timezone.now() - timedelta(minutes=5)
|
||||
|
||||
self.assertFalse(instance.is_updated_since(dt))
|
||||
|
||||
def test_is_updated_since_returns_true_after_update(self):
|
||||
"""
|
||||
Проверяем, что is_updated_since() возвращает True после update()
|
||||
"""
|
||||
|
||||
instance = self.TestModel.objects.create(name='Test Instance')
|
||||
dt = timezone.now()
|
||||
|
||||
time.sleep(0.1)
|
||||
instance.update(save=False)
|
||||
|
||||
self.assertTrue(instance.is_updated_since(dt))
|
||||
|
||||
def test_is_updated_since_returns_false_if_updated_before_dt(self):
|
||||
"""
|
||||
Проверяем, что is_updated_since() возвращает False,
|
||||
если обновление было раньше указанного времени
|
||||
"""
|
||||
|
||||
instance = self.TestModel.objects.create(name='Test Instance')
|
||||
instance.update(save=False)
|
||||
old_updated_at = instance.updated_at
|
||||
|
||||
# Проверяем, что updated_at был раньше, чем через секунду
|
||||
dt = old_updated_at + timedelta(seconds=1)
|
||||
self.assertFalse(instance.is_updated_since(dt))
|
||||
|
||||
def test_multiple_updates(self):
|
||||
"""
|
||||
Проверяем, что повторный вызов update() обновляет время
|
||||
"""
|
||||
|
||||
instance = self.TestModel.objects.create(name='Test Instance')
|
||||
|
||||
instance.update(save=False)
|
||||
first_time = instance.updated_at
|
||||
|
||||
time.sleep(0.1)
|
||||
|
||||
instance.update(save=False)
|
||||
second_time = instance.updated_at
|
||||
|
||||
self.assertNotEqual(first_time, second_time)
|
||||
self.assertGreater(second_time, first_time)
|
||||
100
net/xeaf/rack/tests/models/mixins/uuid_id_mixin_tests.py
Normal file
100
net/xeaf/rack/tests/models/mixins/uuid_id_mixin_tests.py
Normal file
@@ -0,0 +1,100 @@
|
||||
# DRF Rack
|
||||
# Библиотека классов расширений для Django REST Framework
|
||||
#
|
||||
# Автор: Николай В. Анохин <n.anokhin@xeaf.net>
|
||||
# Все права защищены. Лицензия: MIT
|
||||
|
||||
"""
|
||||
Описание класса UuidIdMixinTests
|
||||
"""
|
||||
|
||||
import uuid
|
||||
|
||||
from django.db import connection
|
||||
from django.db import models
|
||||
from django.test import TransactionTestCase
|
||||
|
||||
from net.xeaf.rack.models.mixins import UuidIdMixin
|
||||
|
||||
|
||||
class UuidIdMixinTests(TransactionTestCase):
|
||||
"""
|
||||
Тесты для миксина UuidIdMixin
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
"""
|
||||
Создаем тестовую модель и таблицу для каждого теста
|
||||
"""
|
||||
|
||||
with connection.cursor() as cursor:
|
||||
cursor.execute('PRAGMA foreign_keys = OFF;')
|
||||
|
||||
class TestUuidModel(UuidIdMixin):
|
||||
name = models.CharField(max_length=100)
|
||||
|
||||
class Meta:
|
||||
app_label = 'test'
|
||||
db_table = 'test_uuid_mixin'
|
||||
|
||||
self.TestModel = TestUuidModel
|
||||
|
||||
with connection.schema_editor() as editor:
|
||||
editor.create_model(TestUuidModel)
|
||||
|
||||
def tearDown(self):
|
||||
"""
|
||||
Удаляем таблицу после каждого теста
|
||||
"""
|
||||
|
||||
with connection.schema_editor() as editor:
|
||||
editor.delete_model(self.TestModel)
|
||||
|
||||
with connection.cursor() as cursor:
|
||||
cursor.execute('PRAGMA foreign_keys = ON;')
|
||||
|
||||
def test_id_is_uuid_by_default(self):
|
||||
"""
|
||||
Проверяем, что при создании id автоматически генерируется как UUID
|
||||
"""
|
||||
|
||||
instance = self.TestModel.objects.create(name='Test Instance')
|
||||
|
||||
self.assertIsNotNone(instance.id)
|
||||
self.assertIsInstance(instance.id, uuid.UUID)
|
||||
|
||||
def test_id_is_unique(self):
|
||||
"""
|
||||
Проверяем, что каждый экземпляр получает уникальный UUID
|
||||
"""
|
||||
|
||||
instance1 = self.TestModel.objects.create(name='First')
|
||||
instance2 = self.TestModel.objects.create(name='Second')
|
||||
|
||||
self.assertNotEqual(instance1.id, instance2.id)
|
||||
|
||||
def test_id_is_primary_key(self):
|
||||
"""
|
||||
Проверяем, что id является первичным ключом
|
||||
"""
|
||||
|
||||
field = self.TestModel._meta.get_field('id')
|
||||
self.assertTrue(field.primary_key)
|
||||
|
||||
def test_id_is_editable_false(self):
|
||||
"""
|
||||
Проверяем, что id нельзя редактировать
|
||||
"""
|
||||
|
||||
field = self.TestModel._meta.get_field('id')
|
||||
self.assertFalse(field.editable)
|
||||
|
||||
def test_id_can_be_used_in_queries(self):
|
||||
"""
|
||||
Проверяем, что можно искать по UUID
|
||||
"""
|
||||
|
||||
instance = self.TestModel.objects.create(name='Test Instance')
|
||||
|
||||
found = self.TestModel.objects.get(id=instance.id)
|
||||
self.assertEqual(found.id, instance.id)
|
||||
Reference in New Issue
Block a user