test(core): Interim Unit Model test suite for CenturionModelNote Meta Models

ref: #779 #778
This commit is contained in:
2025-05-30 09:32:16 +09:30
parent 9afca66ad6
commit 637a76f1fe
4 changed files with 291 additions and 0 deletions

View File

@ -0,0 +1,10 @@
import pytest
from core.models.centurion_notes import NoteMetaModel
@pytest.fixture( scope = 'class')
def model(request):
yield NoteMetaModel

View File

@ -0,0 +1,160 @@
import pytest
from core.tests.unit.centurion_sub_abstract.test_unit_centurion_sub_abstract_model import (
CenturionSubAbstractModelInheritedCases,
)
from core.tests.unit.centurion_model_note.test_unit_centurion_model_note_model import (
CenturionNoteModelInheritedCases,
)
@pytest.mark.meta_models
class MetaAbstractModelTestCases(
CenturionNoteModelInheritedCases,
CenturionSubAbstractModelInheritedCases,
):
def test_method_get_url_attribute__is_submodel_set(self, mocker, model_instance, settings):
"""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)
model_instance.id = 1
model_instance.model = model_instance
url_basename = f'v2:_api_centurionmodelnote_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': model_instance._meta.model_name,
'model_id': 1,
'pk': 1
},
None,
None
)
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_centurionmodelnote_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('centurionmodelnote', ''),
'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('centurionmodelnote', ''),
'model_id': model_instance.model.id,
'pk': model_instance.id,
}
class MetaAbstractModelPyTest(
MetaAbstractModelTestCases,
):
pass
@pytest.mark.xfail( reason = 'This model is an abstract model')
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_model_is_abstract(self, model):
assert model._meta.abstract
def test_model_not_proxy(self, model):
assert not model._meta.proxy
def test_model_creation(self):
"""
This test is a duplicate of a test with the same name. As this model
is an abstract model this test is not required.
"""
pass

View File

@ -0,0 +1,120 @@
import pytest
from django.apps import apps
from django.conf import settings
from core.models.centurion_notes import CenturionModelNote
from core.tests.unit.centurion_model_note_meta.test_unit_centurion_model_note_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 ModelNotesMetaModelTestCases(
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.note_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, CenturionModelNote)
or model == CenturionModelNote
):
continue
cls_name: str = f"{model._meta.object_name}MetaModelPyTest"
globals()[cls_name] = type(
cls_name,
(ModelNotesMetaModelTestCases,),
{
'note_model_class': apps.get_model(
app_label = model._meta.app_label,
model_name = str( model._meta.object_name ).replace('CenturionModelNote', '')
),
'model_class': model
}
)

View File

@ -1072,6 +1072,7 @@ markers = [
"meta_models: Selects Meta models",
"model_gitgroup: Selects tests for model `git group`",
"models: Selects all models tests.",
"note_models: Selects all centurion model note models",
"tenancy_models: Selects Tenancy models.",
"unit: Selects all Unit Tests.",
]