From f023901dc4c55fd7fd43f59469753f933eb0a3e5 Mon Sep 17 00:00:00 2001 From: Jon Date: Sun, 15 Jun 2025 14:24:00 +0930 Subject: [PATCH] refactor(settings): Update Test Suite for AppSettings model ref: #833 #834 --- app/fixtures/fresh_db.sql | 13 +- .../app_settings/test_app_settings_api_v2.py | 3 +- .../test_unit_app_settings_model.py | 144 +++++++++++++++--- .../test_unit_app_settings_viewset.py | 3 + app/tests/fixtures/__init__.py | 5 + app/tests/fixtures/model_appsettings.py | 33 ++++ pyproject.toml | 3 +- 7 files changed, 178 insertions(+), 26 deletions(-) create mode 100644 app/tests/fixtures/model_appsettings.py diff --git a/app/fixtures/fresh_db.sql b/app/fixtures/fresh_db.sql index 8b7610b6..23bd3e9f 100644 --- a/app/fixtures/fresh_db.sql +++ b/app/fixtures/fresh_db.sql @@ -101,9 +101,8 @@ CREATE TABLE IF NOT EXISTS "devops_git_group_history" ("modelhistory_ptr_id" int CREATE TABLE IF NOT EXISTS "devops_github_repository_notes" ("modelnotes_ptr_id" integer NOT NULL PRIMARY KEY REFERENCES "core_model_notes" ("id") DEFERRABLE INITIALLY DEFERRED, "model_id" integer NOT NULL REFERENCES "devops_githubrepository" ("gitrepository_ptr_id") DEFERRABLE INITIALLY DEFERRED); CREATE TABLE IF NOT EXISTS "devops_gitlab_repository_notes" ("modelnotes_ptr_id" integer NOT NULL PRIMARY KEY REFERENCES "core_model_notes" ("id") DEFERRABLE INITIALLY DEFERRED, "model_id" integer NOT NULL REFERENCES "devops_gitlabrepository" ("gitrepository_ptr_id") DEFERRABLE INITIALLY DEFERRED); CREATE TABLE IF NOT EXISTS "devops_git_group_notes" ("modelnotes_ptr_id" integer NOT NULL PRIMARY KEY REFERENCES "core_model_notes" ("id") DEFERRABLE INITIALLY DEFERRED, "model_id" integer NOT NULL REFERENCES "devops_gitgroup" ("id") DEFERRABLE INITIALLY DEFERRED); -CREATE TABLE IF NOT EXISTS "access_organization_notes" ("modelnotes_ptr_id" integer NOT NULL PRIMARY KEY REFERENCES "core_model_notes" ("id") DEFERRABLE INITIALLY DEFERRED, "model_id" integer NOT NULL REFERENCES "access_tenant" ("id") DEFERRABLE INITIALLY DEFERRED); CREATE TABLE IF NOT EXISTS "access_organization_history" ("modelhistory_ptr_id" integer NOT NULL PRIMARY KEY REFERENCES "core_model_history" ("id") DEFERRABLE INITIALLY DEFERRED, "model_id" integer NOT NULL REFERENCES "access_tenant" ("id") DEFERRABLE INITIALLY DEFERRED); -CREATE TABLE IF NOT EXISTS "settings_appsettings" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "created" datetime NOT NULL, "modified" datetime NOT NULL, "device_model_is_global" bool NOT NULL, "device_type_is_global" bool NOT NULL, "manufacturer_is_global" bool NOT NULL, "software_is_global" bool NOT NULL, "software_categories_is_global" bool NOT NULL, "global_organization_id" integer NULL REFERENCES "access_tenant" ("id") DEFERRABLE INITIALLY DEFERRED, "owner_organization_id" integer NULL REFERENCES "access_tenant" ("id") DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE IF NOT EXISTS "access_organization_notes" ("modelnotes_ptr_id" integer NOT NULL PRIMARY KEY REFERENCES "core_model_notes" ("id") DEFERRABLE INITIALLY DEFERRED, "model_id" integer NOT NULL REFERENCES "access_tenant" ("id") DEFERRABLE INITIALLY DEFERRED); CREATE TABLE IF NOT EXISTS "settings_usersettings" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "created" datetime NOT NULL, "modified" datetime NOT NULL, "default_organization_id" integer NULL REFERENCES "access_tenant" ("id") DEFERRABLE INITIALLY DEFERRED, "user_id" integer NOT NULL REFERENCES "auth_user" ("id") DEFERRABLE INITIALLY DEFERRED, "timezone" varchar(32) NOT NULL, "browser_mode" integer NOT NULL); CREATE TABLE IF NOT EXISTS "access_company" ("entity_ptr_id" integer NOT NULL PRIMARY KEY REFERENCES "access_entity" ("id") DEFERRABLE INITIALLY DEFERRED, "name" varchar(80) NOT NULL); CREATE TABLE IF NOT EXISTS "access_entity" ("is_global" bool NOT NULL, "model_notes" text NULL, "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "created" datetime NOT NULL, "modified" datetime NOT NULL, "organization_id" integer NOT NULL REFERENCES "access_tenant" ("id") DEFERRABLE INITIALLY DEFERRED, "entity_type" varchar(30) NOT NULL); @@ -220,15 +219,17 @@ CREATE TABLE IF NOT EXISTS "project_management_projecttype" ("id" integer NOT NU CREATE TABLE IF NOT EXISTS "project_management_projecttype_audithistory" ("centurionaudit_ptr_id" integer NOT NULL PRIMARY KEY REFERENCES "core_audithistory" ("id") DEFERRABLE INITIALLY DEFERRED, "model_id" integer NOT NULL REFERENCES "project_management_projecttype" ("id") DEFERRABLE INITIALLY DEFERRED); CREATE TABLE IF NOT EXISTS "project_management_projecttype_centurionmodelnote" ("centurionmodelnote_ptr_id" integer NOT NULL PRIMARY KEY REFERENCES "core_centurionmodelnote" ("id") DEFERRABLE INITIALLY DEFERRED, "model_id" integer NOT NULL REFERENCES "project_management_projecttype" ("id") DEFERRABLE INITIALLY DEFERRED); CREATE TABLE IF NOT EXISTS "django_session" ("session_key" varchar(40) NOT NULL PRIMARY KEY, "session_data" text NOT NULL, "expire_date" datetime NOT NULL); +CREATE TABLE IF NOT EXISTS "settings_appsettings" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "created" datetime NOT NULL, "modified" datetime NOT NULL, "device_model_is_global" bool NOT NULL, "device_type_is_global" bool NOT NULL, "manufacturer_is_global" bool NOT NULL, "software_is_global" bool NOT NULL, "software_categories_is_global" bool NOT NULL, "global_organization_id" integer NULL REFERENCES "access_tenant" ("id") DEFERRABLE INITIALLY DEFERRED, "owner_organization_id" integer NULL REFERENCES "access_tenant" ("id") DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE IF NOT EXISTS "settings_appsettings_audithistory" ("centurionaudit_ptr_id" integer NOT NULL PRIMARY KEY REFERENCES "core_audithistory" ("id") DEFERRABLE INITIALLY DEFERRED, "model_id" integer NOT NULL REFERENCES "settings_appsettings" ("id") DEFERRABLE INITIALLY DEFERRED); CREATE TABLE IF NOT EXISTS "social_auth_association" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "server_url" varchar(255) NOT NULL, "handle" varchar(255) NOT NULL, "secret" varchar(255) NOT NULL, "issued" integer NOT NULL, "lifetime" integer NOT NULL, "assoc_type" varchar(64) NOT NULL); CREATE TABLE IF NOT EXISTS "social_auth_code" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "email" varchar(254) NOT NULL, "code" varchar(32) NOT NULL, "verified" bool NOT NULL, "timestamp" datetime NOT NULL); CREATE TABLE IF NOT EXISTS "social_auth_nonce" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "server_url" varchar(255) NOT NULL, "timestamp" integer NOT NULL, "salt" varchar(65) NOT NULL); CREATE TABLE IF NOT EXISTS "social_auth_usersocialauth" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "provider" varchar(32) NOT NULL, "uid" varchar(255) NOT NULL, "user_id" integer NOT NULL REFERENCES "auth_user" ("id") DEFERRABLE INITIALLY DEFERRED, "created" datetime NOT NULL, "modified" datetime NOT NULL, "extra_data" text NOT NULL CHECK ((JSON_VALID("extra_data") OR "extra_data" IS NULL))); CREATE TABLE IF NOT EXISTS "social_auth_partial" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "token" varchar(32) NOT NULL, "next_step" smallint unsigned NOT NULL CHECK ("next_step" >= 0), "backend" varchar(32) NOT NULL, "timestamp" datetime NOT NULL, "data" text NOT NULL CHECK ((JSON_VALID("data") OR "data" IS NULL))); DELETE FROM sqlite_sequence; -INSERT INTO sqlite_sequence VALUES('django_migrations',214); -INSERT INTO sqlite_sequence VALUES('django_content_type',205); -INSERT INTO sqlite_sequence VALUES('auth_permission',865); +INSERT INTO sqlite_sequence VALUES('django_migrations',215); +INSERT INTO sqlite_sequence VALUES('django_content_type',206); +INSERT INTO sqlite_sequence VALUES('auth_permission',869); INSERT INTO sqlite_sequence VALUES('auth_group',0); INSERT INTO sqlite_sequence VALUES('auth_user',0); INSERT INTO sqlite_sequence VALUES('core_notes',0); @@ -237,7 +238,6 @@ INSERT INTO sqlite_sequence VALUES('core_ticket',0); INSERT INTO sqlite_sequence VALUES('core_ticketcomment',0); INSERT INTO sqlite_sequence VALUES('core_ticketlinkeditem',0); INSERT INTO sqlite_sequence VALUES('settings_externallink',0); -INSERT INTO sqlite_sequence VALUES('settings_appsettings',1); INSERT INTO sqlite_sequence VALUES('settings_usersettings',0); INSERT INTO sqlite_sequence VALUES('access_entity',0); INSERT INTO sqlite_sequence VALUES('core_ticketbase',0); @@ -283,6 +283,7 @@ INSERT INTO sqlite_sequence VALUES('project_management_project',0); INSERT INTO sqlite_sequence VALUES('project_management_projectmilestone',0); INSERT INTO sqlite_sequence VALUES('project_management_projectstate',0); INSERT INTO sqlite_sequence VALUES('project_management_projecttype',0); +INSERT INTO sqlite_sequence VALUES('settings_appsettings',1); INSERT INTO sqlite_sequence VALUES('social_auth_association',0); INSERT INTO sqlite_sequence VALUES('social_auth_code',0); INSERT INTO sqlite_sequence VALUES('social_auth_nonce',0); diff --git a/app/settings/tests/unit/app_settings/test_app_settings_api_v2.py b/app/settings/tests/unit/app_settings/test_app_settings_api_v2.py index af93e6cc..f3876f06 100644 --- a/app/settings/tests/unit/app_settings/test_app_settings_api_v2.py +++ b/app/settings/tests/unit/app_settings/test_app_settings_api_v2.py @@ -1,6 +1,5 @@ import django import pytest -import unittest from django.contrib.auth.models import Permission from django.contrib.contenttypes.models import ContentType @@ -22,6 +21,8 @@ User = django.contrib.auth.get_user_model() +@pytest.mark.model_appsettings +@pytest.mark.module_settings class AppSettingsAPI( TestCase, APICommonFields diff --git a/app/settings/tests/unit/app_settings/test_unit_app_settings_model.py b/app/settings/tests/unit/app_settings/test_unit_app_settings_model.py index be6d3bca..38abfdd1 100644 --- a/app/settings/tests/unit/app_settings/test_unit_app_settings_model.py +++ b/app/settings/tests/unit/app_settings/test_unit_app_settings_model.py @@ -1,28 +1,136 @@ - -from django.test import TestCase, Client - import pytest -import unittest -import requests + +from django.db import models + + +from core.tests.unit.centurion_abstract.test_unit_centurion_abstract_model import ( + CenturionAbstractModelInheritedCases +) -@pytest.mark.skip(reason="to be written") -def test_app_settings_only_super_admin_can_access(): - """ Only super admin can access app settings """ +@pytest.mark.model_appsettings +class AppSettingsModelTestCases( + CenturionAbstractModelInheritedCases +): + + + @property + def parameterized_class_attributes(self): + + return { + '_notes_enabled': { + 'value': False + }, + 'model_tag': { + 'type': models.fields.NOT_PROVIDED, + 'value': models.fields.NOT_PROVIDED + }, + } + + + @property + def parameterized_model_fields(self): + + return { + 'model_notes': { + 'blank': models.fields.NOT_PROVIDED, + 'default': models.fields.NOT_PROVIDED, + 'field_type': models.CharField, + 'null': models.fields.NOT_PROVIDED, + 'unique': models.fields.NOT_PROVIDED, + }, + 'organization': { + 'blank': models.fields.NOT_PROVIDED, + 'default': models.fields.NOT_PROVIDED, + 'field_type': models.CharField, + 'null': models.fields.NOT_PROVIDED, + 'unique': models.fields.NOT_PROVIDED, + }, + 'owner_organization': { + 'blank': True, + 'default': models.fields.NOT_PROVIDED, + 'field_type': models.ForeignKey, + 'null': True, + 'unique': False, + }, + 'device_model_is_global': { + 'blank': False, + 'default': False, + 'field_type': models.BooleanField, + 'null': False, + 'unique': False, + }, + 'device_type_is_global': { + 'blank': False, + 'default': False, + 'field_type': models.BooleanField, + 'null': False, + 'unique': False, + }, + 'manufacturer_is_global': { + 'blank': False, + 'default': False, + 'field_type': models.BooleanField, + 'null': False, + 'unique': False, + }, + 'software_is_global': { + 'blank': False, + 'default': False, + 'field_type': models.BooleanField, + 'null': False, + 'unique': False, + }, + 'software_categories_is_global': { + 'blank': False, + 'default': False, + 'field_type': models.BooleanField, + 'null': False, + 'unique': False, + }, + 'owner_organization': { + 'blank': True, + 'default': models.fields.NOT_PROVIDED, + 'field_type': models.ForeignKey, + 'null': True, + 'unique': False, + }, + 'modified': { + 'blank': False, + 'default': models.fields.NOT_PROVIDED, + 'field_type': models.DateTimeField, + 'null': False, + 'unique': False, + }, + } + + + +class AppSettingsModelInheritedCases( + AppSettingsModelTestCases, +): pass -@pytest.mark.skip(reason="to be written") -def test_app_settings_software_is_global_organization_must_be_set(): - """ If field software_is_global=true an organization must be set """ - pass +@pytest.mark.module_settings +class AppSettingsModelPyTest( + AppSettingsModelTestCases, +): -@pytest.mark.skip(reason="to be written") -def test_app_settings_software_is_global_create_software(): - """ If field software_is_global=true on software creation regardless of user settings - software is created in global organization with global=true - """ - pass + def test_model_tag_defined(self, model): + """ Model Tag + Ensure that the model has a tag defined. + """ + + pytest.xfail( reason = 'Model does not require tag' ) + + def test_method_value_not_default___str__(self, model, model_instance ): + """Test Method + + Ensure method `__str__` does not return the default value. + """ + + pytest.xfail( reason = 'Model does not require this function' ) diff --git a/app/settings/tests/unit/app_settings/test_unit_app_settings_viewset.py b/app/settings/tests/unit/app_settings/test_unit_app_settings_viewset.py index 2cc2f19a..b7af3a0b 100644 --- a/app/settings/tests/unit/app_settings/test_unit_app_settings_viewset.py +++ b/app/settings/tests/unit/app_settings/test_unit_app_settings_viewset.py @@ -1,3 +1,4 @@ +import pytest from django.test import Client, TestCase from rest_framework.reverse import reverse @@ -8,6 +9,8 @@ from settings.viewsets.app_settings import ViewSet +@pytest.mark.model_appsettings +@pytest.mark.module_settings class AppSettingsViewsetList( ModelRetrieveUpdateViewSetInheritedCases, TestCase, diff --git a/app/tests/fixtures/__init__.py b/app/tests/fixtures/__init__.py index f7571c35..e880d1fe 100644 --- a/app/tests/fixtures/__init__.py +++ b/app/tests/fixtures/__init__.py @@ -13,6 +13,11 @@ from .mixin_centurion import ( mixin_centurion, ) +from .model_appsettings import ( + kwargs_appsettings, + model_appsettings, +) + from .model_centurionaudit import ( kwargs_centurionaudit, model_centurionaudit, diff --git a/app/tests/fixtures/model_appsettings.py b/app/tests/fixtures/model_appsettings.py new file mode 100644 index 00000000..51a03de5 --- /dev/null +++ b/app/tests/fixtures/model_appsettings.py @@ -0,0 +1,33 @@ +import datetime +import pytest + +from settings.models.app_settings import AppSettings + +@pytest.fixture( scope = 'class') +def model_appsettings(): + + yield AppSettings + + +@pytest.fixture( scope = 'class') +def kwargs_appsettings( django_db_blocker, model_user ): + + random_str = str(datetime.datetime.now(tz=datetime.timezone.utc)) + + with django_db_blocker.unblock(): + + user = model_user.objects.create( + username = 'a'+random_str, + password = 'password' + ) + + kwargs = { + 'device_model_is_global': False, + } + + yield kwargs.copy() + + with django_db_blocker.unblock(): + + user.delete() + diff --git a/pyproject.toml b/pyproject.toml index fba5cffd..0d7ea6be 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1073,6 +1073,7 @@ markers = [ "meta_models: Selects Meta models", "mixin: Selects all mixin test cases.", "mixin_centurion: Selects all centurion mixin test cases.", + "model_appsettings: Selects tests for model app settings.", "model_configgroups: Selects Config Group tests.", "model_configgrouphosts: Selects Config Group Hosts tests.", "model_configgroupsoftware: Selects Config Group Software tests.", @@ -1122,7 +1123,7 @@ markers = [ "module_itim: Selects all tests from module ITIM.", "module_itops: Selects all tests from module IT OPS.", "module_project_management: Selects all tests from module Project Management.", - "module_setings: Selects all tests from module settings.", + "module_settings: Selects all tests from module settings.", "note_models: Selects all centurion model note models", "permissions: selects all permission related tests.", "serializer: Selects all serializer tests",