test(core): Initial Unit Model Test Cases for CenturionAudit Model

ref: #772 #759
This commit is contained in:
2025-05-25 01:56:53 +09:30
parent d0ce759635
commit 16bbb3328b
7 changed files with 243 additions and 23 deletions

View File

@ -88,7 +88,9 @@ class ModelTestCases(
del instance
del apps.all_models['core']['mockmodel']
if 'mockmodel' in apps.all_models['core']:
del apps.all_models['core']['mockmodel']

View File

@ -1,4 +1,5 @@
import datetime
import django
import pytest
import os
import sqlite3
@ -12,7 +13,7 @@ from django.test import (
from access.models.tenant import Tenant
User = django.contrib.auth.get_user_model()
@pytest.fixture(scope="session", autouse = True)
def load_sqlite_fixture(django_db_setup, django_db_blocker):
@ -726,3 +727,23 @@ def fake_view():
yield fake_view
del fake_view
@pytest.fixture(scope = 'class')
def user(django_db_blocker):
with django_db_blocker.unblock():
random_str = str(datetime.datetime.now(tz=datetime.timezone.utc))
user = User.objects.create(
username="test_user-" + random_str,
password="password"
)
yield user
with django_db_blocker.unblock():
user.delete()

View File

@ -0,0 +1,38 @@
# Generated by Django 5.1.9 on 2025-05-24 17:20
import core.models.centurion
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('core', '0024_centurionaudit'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.AlterField(
model_name='centurionaudit',
name='action',
field=models.IntegerField(choices=[(1, 'Create'), (2, 'Update'), (3, 'Delete')], help_text='History action performed', null=True, validators=[core.models.centurion.CenturionModel.validate_field_not_none], verbose_name='Action'),
),
migrations.AlterField(
model_name='centurionaudit',
name='after',
field=models.JSONField(blank=True, help_text='Value Change to', null=True, validators=[core.models.centurion.CenturionModel.validate_field_not_none], verbose_name='After'),
),
migrations.AlterField(
model_name='centurionaudit',
name='before',
field=models.JSONField(blank=True, help_text='Value before Change', null=True, validators=[core.models.centurion.CenturionModel.validate_field_not_none], verbose_name='Before'),
),
migrations.AlterField(
model_name='centurionaudit',
name='user',
field=models.ForeignKey(default=None, help_text='User whom performed the action', on_delete=django.db.models.deletion.DO_NOTHING, to=settings.AUTH_USER_MODEL, validators=[core.models.centurion.CenturionModel.validate_field_not_none], verbose_name='User'),
preserve_default=False,
),
]

View File

@ -59,7 +59,6 @@ class CenturionAudit(
before = models.JSONField(
blank = True,
default = None,
help_text = 'Value before Change',
null = True,
validators = [
@ -71,7 +70,6 @@ class CenturionAudit(
after = models.JSONField(
blank = True,
default = None,
help_text = 'Value Change to',
null = True,
validators = [
@ -89,7 +87,6 @@ class CenturionAudit(
action = models.IntegerField(
blank = False,
choices = Actions,
default = None,
help_text = 'History action performed',
null = True,
validators = [
@ -102,7 +99,7 @@ class CenturionAudit(
settings.AUTH_USER_MODEL,
blank = False,
help_text = 'User whom performed the action',
null = True,
null = False,
on_delete = models.DO_NOTHING,
validators = [
CenturionModel.validate_field_not_none,
@ -143,7 +140,7 @@ class CenturionAudit(
to implement this method.
"""
if not isinstance(self, CenturionAudit):
if type(self) is not CenturionAudit:
raise NotImplementedError(
'Audit sub models must implement this method to populate fields'

View File

@ -211,6 +211,17 @@ class CenturionAbstractModelInheritedCases(
):
parameterized_class_attributes = {
'page_layout': {
'type': list,
},
'table_fields': {
'type': list,
}
}
def test_model_creation(self, model):
model_object = model.objects.create(
@ -693,7 +704,7 @@ class CenturionAbstractModelPyTest(
Ensure method `get_url` calls reverse
"""
reverse = mocker.patch('rest_framework.reverse._reverse', return_value = None)
reverse = mocker.patch('rest_framework.reverse._reverse', return_value = 'None')
model_instance.id = 1
url_basename = f'v2:_api_{model_instance._meta.model_name}-detail'

View File

@ -1,14 +1,10 @@
# import pytest
import pytest
# from core.models.audit import CenturionAudit
from core.models.audit import CenturionAudit
# @pytest.fixture( scope = 'class')
# def model(request):
@pytest.fixture( scope = 'class')
def model(request):
# request.cls.model = CenturionAudit
# yield request.cls.model
# del request.cls.model
yield CenturionAudit

View File

@ -1,14 +1,97 @@
import inspect
import pytest
from django.apps import apps
from django.contrib.contenttypes.models import ContentType
from django.db import models
from core.models.audit import CenturionAudit
from core.tests.unit.centurion_abstract.test_unit_centurion_abstract_model import (
CenturionAbstractModelInheritedCases
)
@pytest.mark.models
class CenturionAuditModelTestCases:
class CenturionAuditModelTestCases(
CenturionAbstractModelInheritedCases
):
# @pytest.fixture( scope = 'class', autouse = True)
# def setup_class(cls, model):
# pass
pass
kwargs_create_item = {
'before': {},
'after': {
'after_key': 'after_value'
},
'action': CenturionAudit.Actions.ADD,
'user': 'fixture sets value',
'content_type': 'fixture sets value',
}
parameterized_class_attributes = {
'_audit_enabled': {
'value': False,
},
'_notes_enabled': {
'value': False,
}
}
parameterized_model_fields = {
'content_type': {
'blank': True,
'default': models.fields.NOT_PROVIDED,
'field_type': models.IntegerField,
'null': False,
'unique': False,
},
'before': {
'blank': True,
'default': models.fields.NOT_PROVIDED,
'field_type': models.JSONField,
'null': True,
'unique': False,
},
'after': {
'blank': True,
'default': models.fields.NOT_PROVIDED,
'field_type': models.JSONField,
'null': True,
'unique': False,
},
'action': {
'blank': False,
'default': models.fields.NOT_PROVIDED,
'field_type': models.IntegerField,
'null': True,
'unique': False,
},
'user': {
'blank': False,
'default': models.fields.NOT_PROVIDED,
'field_type': models.ForeignKey,
'null': False,
'unique': False,
}
}
@pytest.fixture( scope = 'class', autouse = True )
def setup_vars(self, django_db_blocker, user, model):
with django_db_blocker.unblock():
content_type = ContentType.objects.get(
app_label = model._meta.app_label,
model = model._meta.model_name,
)
self.kwargs_create_item.update({
'content_type': content_type,
'user': user,
})
class CenturionAuditModelInheritedCases(
@ -22,4 +105,76 @@ class CenturionAuditModelInheritedCases(
class CenturionAuditModelPyTest(
CenturionAuditModelTestCases,
):
pass
def test_method_clean_fields_default_attributes(self, model_instance):
"""Test Class Method
Ensure method `clean_fields` has the defined default attributes.
"""
sig = inspect.signature(model_instance.clean_fields)
exclude = sig.parameters['exclude'].default
assert(
exclude == None
)
def test_method_clean_fields_calls_super_clean_fields(self, mocker, model_instance):
"""Test Class Method
Ensure method `clean_fields` calls `super().clean_fields` with the defined attributes.
"""
super_clean_fields = mocker.patch('core.models.centurion.CenturionModel.clean_fields', return_value = None)
model_instance.clean_fields()
super_clean_fields.assert_called_with(
exclude = None
)
def test_method_clean_fields_not_implemented_exception(self, mocker, model):
"""Test Class Method
Ensure method `clean_fields` raises an exception if the child model
does not implement its own method of the same name.
"""
class MockModel(model):
class Meta:
app_label = 'core'
verbose_name = 'mock instance'
managed = False
mock_model = MockModel()
del apps.all_models['core']['mockmodel']
super_clean_fields = mocker.patch('core.models.centurion.CenturionModel.full_clean', return_value = None)
with pytest.raises(NotImplementedError):
mock_model.clean_fields()
def test_method_get_model_history_default_attributes(self, model_instance):
"""Test Class Method
Ensure method `get_model_history` has the defined default attributes.
"""
sig = inspect.signature(model_instance.get_model_history)
model = sig.parameters['model'].default
assert(
model == inspect._empty
)