diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 020d6191..49cd8e6e 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -8,5 +8,6 @@ "qwtel.sqlite-viewer", "jebbs.markdown-extended", "william-voyek.vscode-nginx", + "detachhead.basedpyright", ] } \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index 76696de5..f1a8ec31 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -25,4 +25,5 @@ "green": 90 }, "telemetry.feedback.enabled": false, + "python.languageServer": "None", } \ No newline at end of file diff --git a/app/core/tests/unit/centurion_audit_meta/test_unit_centurion_audit_meta_model.py b/app/core/tests/unit/centurion_audit_meta/test_unit_centurion_audit_meta_model.py index 4348443f..7bfdbb76 100644 --- a/app/core/tests/unit/centurion_audit_meta/test_unit_centurion_audit_meta_model.py +++ b/app/core/tests/unit/centurion_audit_meta/test_unit_centurion_audit_meta_model.py @@ -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, + } + diff --git a/app/core/tests/unit/centurion_audit_meta/test_unit_meta_audit_history_model.py b/app/core/tests/unit/centurion_audit_meta/test_unit_meta_audit_history_model.py new file mode 100644 index 00000000..37eda8ab --- /dev/null +++ b/app/core/tests/unit/centurion_audit_meta/test_unit_meta_audit_history_model.py @@ -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 + } + )