test(core): Dynamic Unit Test Suites for Meta Models AuditHistory

ref: #775 #759 #767
This commit is contained in:
2025-05-28 18:29:20 +09:30
parent adc1c8fba7
commit 416b6f5a75
4 changed files with 191 additions and 1 deletions

View File

@ -8,5 +8,6 @@
"qwtel.sqlite-viewer",
"jebbs.markdown-extended",
"william-voyek.vscode-nginx",
"detachhead.basedpyright",
]
}

View File

@ -25,4 +25,5 @@
"green": 90
},
"telemetry.feedback.enabled": false,
"python.languageServer": "None",
}

View File

@ -71,7 +71,75 @@ class MetaAbstractModelInheritedCases(
MetaAbstractModelTestCases,
):
pass
@pytest.mark.xfail( reason = 'This model does not require a tag')
def test_model_tag_defined(self, model):
""" Model Tag
Ensure that the model has a tag defined.
"""
assert model.model_tag is not None
def test_method_get_url_attribute__is_submodel_set(self, mocker, model_instance, audit_model):
"""Test Class Method
Ensure method `get_url` calls reverse
"""
site_path = '/module/page/1'
assert model_instance._is_submodel # Test Failsafe. Confirm state
reverse = mocker.patch('rest_framework.reverse._reverse', return_value = site_path)
instance = audit_model()
instance.id = 1
model_instance.id = 1
model_instance.model = instance
url_basename = f'v2:_api_centurionaudit_sub-detail'
url = model_instance.get_url( relative = True)
reverse.assert_called_with(
url_basename,
None,
{
'app_label': model_instance._meta.app_label,
'model_name': str(model_instance._meta.model_name).replace('audithistory', ''),
'model_id': 1,
'pk': 1
},
None,
None
)
def test_method_get_url_kwargs(self, mocker, model_instance, audit_model):
"""Test Class Method
Ensure method `get_url_kwargs` returns the correct value.
"""
instance = audit_model()
instance.id = 1
model_instance.id = 1
model_instance.model = instance
url = model_instance.get_url_kwargs()
assert model_instance.get_url_kwargs() == {
'app_label': model_instance._meta.app_label,
'model_name': str(model_instance._meta.model_name).replace('audithistory', ''),
'model_id': model_instance.model.id,
'pk': model_instance.id,
}

View File

@ -0,0 +1,120 @@
import pytest
from django.apps import apps
from django.conf import settings
from core.models.audit import CenturionAudit
from core.tests.unit.centurion_audit_meta.test_unit_centurion_audit_meta_model import (
MetaAbstractModelInheritedCases
)
def get_models( excludes: list[ str ] = [] ) -> list[ tuple ]:
"""Fetch models from Centurion Apps
Args:
excludes (list[ str ]): Words that may be in a models name to exclude
Returns:
list[ tuple ]: Centurion ERP Only models
"""
models: list = []
model_apps: list = []
exclude_model_apps = [
'django',
'django_celery_results',
'django_filters',
'drf_spectacular',
'drf_spectacular_sidecar',
'coresheaders',
'corsheaders',
'rest_framework',
'rest_framework_json_api',
'social_django',
]
for app in settings.INSTALLED_APPS:
app = app.split('.')[0]
if app in exclude_model_apps:
continue
model_apps += [ app ]
for model in apps.get_models():
if model._meta.app_label not in model_apps:
continue
skip = False
for exclude in excludes:
if exclude in str(model._meta.model_name):
skip = True
break
if skip:
continue
models += [ model ]
return models
class AuditHistoryMetaModelTestCases(
MetaAbstractModelInheritedCases
):
"""AuditHistory Meta Model Test Cases
This test suite is the base for the dynamic tests that are created
during pytest discover.
"""
@pytest.fixture( scope = 'class' )
def audit_model(self, request):
return request.cls.audit_model_class
@pytest.fixture( scope = 'class' )
def model(self, request):
return request.cls.model_class
@pytest.mark.skip( reason = 'ToDo: Figure out how to dynomagic add audit_model instance' )
def test_model_creation(self, model, user):
pass
for model in get_models():
if(
not issubclass(model, CenturionAudit)
or model == CenturionAudit
):
continue
cls_name: str = f"{model._meta.object_name}MetaModelPyTest"
globals()[cls_name] = type(
cls_name,
(AuditHistoryMetaModelTestCases,),
{
'audit_model_class': apps.get_model(
app_label = model._meta.app_label,
model_name = str( model._meta.object_name ).replace('AuditHistory', '')
),
'model_class': model
}
)