From 4c53c92a228dc27cdedbc91ab452e21f5fbaf069 Mon Sep 17 00:00:00 2001 From: Jon Date: Sat, 14 Jun 2025 13:41:44 +0930 Subject: [PATCH] refactor(project_management): Update Test Suite for ProjectState model ref: #833 #831 --- app/fixtures/fresh_db.sql | 14 ++-- .../tests/unit/project_state/conftest.py | 19 +++++ .../test_project_state_api_v2.py | 23 +++--- .../test_unit_project_state_model.py | 79 +++++++++++++++++-- .../test_unit_project_state_viewset.py | 4 + app/tests/fixtures/__init__.py | 5 ++ app/tests/fixtures/model_projectstate.py | 29 +++++++ pyproject.toml | 1 + 8 files changed, 151 insertions(+), 23 deletions(-) create mode 100644 app/project_management/tests/unit/project_state/conftest.py create mode 100644 app/tests/fixtures/model_projectstate.py diff --git a/app/fixtures/fresh_db.sql b/app/fixtures/fresh_db.sql index db88c5ef..340c139b 100644 --- a/app/fixtures/fresh_db.sql +++ b/app/fixtures/fresh_db.sql @@ -10,7 +10,6 @@ CREATE TABLE IF NOT EXISTS "auth_group" ("id" integer NOT NULL PRIMARY KEY AUTOI CREATE TABLE IF NOT EXISTS "auth_user" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "password" varchar(128) NOT NULL, "last_login" datetime NULL, "is_superuser" bool NOT NULL, "username" varchar(150) NOT NULL UNIQUE, "last_name" varchar(150) NOT NULL, "email" varchar(254) NOT NULL, "is_staff" bool NOT NULL, "is_active" bool NOT NULL, "date_joined" datetime NOT NULL, "first_name" varchar(150) NOT NULL); CREATE TABLE IF NOT EXISTS "access_teamusers" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "manager" bool NOT NULL, "created" datetime NOT NULL, "modified" datetime NOT NULL, "team_id" integer NOT NULL REFERENCES "access_team" ("group_ptr_id") DEFERRABLE INITIALLY DEFERRED, "user_id" integer NOT NULL REFERENCES "auth_user" ("id") DEFERRABLE INITIALLY DEFERRED); CREATE TABLE IF NOT EXISTS "project_management_project_team_members" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "project_id" integer NOT NULL REFERENCES "project_management_project" ("id") DEFERRABLE INITIALLY DEFERRED, "user_id" integer NOT NULL REFERENCES "auth_user" ("id") DEFERRABLE INITIALLY DEFERRED); -CREATE TABLE IF NOT EXISTS "project_management_projectstate" ("is_global" bool NOT NULL, "model_notes" text NULL, "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "created" datetime NOT NULL, "modified" datetime NOT NULL, "name" varchar(50) NOT NULL UNIQUE, "is_completed" bool NOT NULL, "runbook_id" integer NULL REFERENCES "assistance_knowledgebase" ("id") DEFERRABLE INITIALLY DEFERRED, "organization_id" integer NOT NULL REFERENCES "access_tenant" ("id") DEFERRABLE INITIALLY DEFERRED); CREATE TABLE IF NOT EXISTS "project_management_projecttype" ("is_global" bool NOT NULL, "model_notes" text NULL, "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "created" datetime NOT NULL, "modified" datetime NOT NULL, "name" varchar(50) NOT NULL UNIQUE, "runbook_id" integer NULL REFERENCES "assistance_knowledgebase" ("id") DEFERRABLE INITIALLY DEFERRED, "organization_id" integer NOT NULL REFERENCES "access_tenant" ("id") DEFERRABLE INITIALLY DEFERRED); CREATE TABLE IF NOT EXISTS "itim_service_port" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "service_id" integer NOT NULL REFERENCES "itim_service" ("id") DEFERRABLE INITIALLY DEFERRED, "port_id" integer NOT NULL REFERENCES "itim_port" ("id") DEFERRABLE INITIALLY DEFERRED); CREATE TABLE IF NOT EXISTS "core_ticket_assigned_teams" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "ticket_id" integer NOT NULL REFERENCES "core_ticket" ("id") DEFERRABLE INITIALLY DEFERRED, "team_id" integer NOT NULL REFERENCES "access_team" ("group_ptr_id") DEFERRABLE INITIALLY DEFERRED); @@ -103,8 +102,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_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 "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_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 "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_company" ("entity_ptr_id" integer NOT NULL PRIMARY KEY REFERENCES "access_entity" ("id") DEFERRABLE INITIALLY DEFERRED, "name" varchar(80) NOT NULL); @@ -215,6 +214,9 @@ CREATE TABLE IF NOT EXISTS "project_management_project_centurionmodelnote" ("cen CREATE TABLE IF NOT EXISTS "project_management_projectmilestone" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "modified" datetime NOT NULL, "name" varchar(100) NOT NULL UNIQUE, "start_date" datetime NULL, "finish_date" datetime NULL, "created" datetime NOT NULL, "organization_id" integer NOT NULL REFERENCES "access_tenant" ("id") DEFERRABLE INITIALLY DEFERRED, "project_id" integer NOT NULL REFERENCES "project_management_project" ("id") DEFERRABLE INITIALLY DEFERRED, "description" text NULL); CREATE TABLE IF NOT EXISTS "project_management_projectmilestone_audithistory" ("centurionaudit_ptr_id" integer NOT NULL PRIMARY KEY REFERENCES "core_audithistory" ("id") DEFERRABLE INITIALLY DEFERRED, "model_id" integer NOT NULL REFERENCES "project_management_projectmilestone" ("id") DEFERRABLE INITIALLY DEFERRED); CREATE TABLE IF NOT EXISTS "project_management_projectmilestone_centurionmodelnote" ("centurionmodelnote_ptr_id" integer NOT NULL PRIMARY KEY REFERENCES "core_centurionmodelnote" ("id") DEFERRABLE INITIALLY DEFERRED, "model_id" integer NOT NULL REFERENCES "project_management_projectmilestone" ("id") DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE IF NOT EXISTS "project_management_projectstate" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "created" datetime NOT NULL, "modified" datetime NOT NULL, "name" varchar(50) NOT NULL UNIQUE, "is_completed" bool NOT NULL, "organization_id" integer NOT NULL REFERENCES "access_tenant" ("id") DEFERRABLE INITIALLY DEFERRED, "runbook_id" integer NULL REFERENCES "assistance_knowledgebase" ("id") DEFERRABLE INITIALLY DEFERRED, "model_notes" text NULL); +CREATE TABLE IF NOT EXISTS "project_management_projectstate_audithistory" ("centurionaudit_ptr_id" integer NOT NULL PRIMARY KEY REFERENCES "core_audithistory" ("id") DEFERRABLE INITIALLY DEFERRED, "model_id" integer NOT NULL REFERENCES "project_management_projectstate" ("id") DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE IF NOT EXISTS "project_management_projectstate_centurionmodelnote" ("centurionmodelnote_ptr_id" integer NOT NULL PRIMARY KEY REFERENCES "core_centurionmodelnote" ("id") DEFERRABLE INITIALLY DEFERRED, "model_id" integer NOT NULL REFERENCES "project_management_projectstate" ("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 "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); @@ -222,12 +224,11 @@ CREATE TABLE IF NOT EXISTS "social_auth_nonce" ("id" integer NOT NULL PRIMARY KE 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',212); -INSERT INTO sqlite_sequence VALUES('django_content_type',201); -INSERT INTO sqlite_sequence VALUES('auth_permission',849); +INSERT INTO sqlite_sequence VALUES('django_migrations',213); +INSERT INTO sqlite_sequence VALUES('django_content_type',203); +INSERT INTO sqlite_sequence VALUES('auth_permission',857); INSERT INTO sqlite_sequence VALUES('auth_group',0); INSERT INTO sqlite_sequence VALUES('auth_user',0); -INSERT INTO sqlite_sequence VALUES('project_management_projectstate',0); INSERT INTO sqlite_sequence VALUES('project_management_projecttype',0); INSERT INTO sqlite_sequence VALUES('core_notes',0); INSERT INTO sqlite_sequence VALUES('core_relatedtickets',0); @@ -279,6 +280,7 @@ INSERT INTO sqlite_sequence VALUES('itim_service_dependent_service',0); INSERT INTO sqlite_sequence VALUES('itim_service',0); 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('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/project_management/tests/unit/project_state/conftest.py b/app/project_management/tests/unit/project_state/conftest.py new file mode 100644 index 00000000..7f71fa8f --- /dev/null +++ b/app/project_management/tests/unit/project_state/conftest.py @@ -0,0 +1,19 @@ +import pytest + + + +@pytest.fixture( scope = 'class') +def model(model_projectstate): + + yield model_projectstate + + +@pytest.fixture( scope = 'class', autouse = True) +def model_kwargs(request, kwargs_projectstate): + + request.cls.kwargs_create_item = kwargs_projectstate.copy() + + yield kwargs_projectstate.copy() + + if hasattr(request.cls, 'kwargs_create_item'): + del request.cls.kwargs_create_item diff --git a/app/project_management/tests/unit/project_state/test_project_state_api_v2.py b/app/project_management/tests/unit/project_state/test_project_state_api_v2.py index c4e082ba..42ba745f 100644 --- a/app/project_management/tests/unit/project_state/test_project_state_api_v2.py +++ b/app/project_management/tests/unit/project_state/test_project_state_api_v2.py @@ -1,21 +1,18 @@ import django import pytest -import unittest from django.contrib.auth.models import Permission from django.contrib.contenttypes.models import ContentType from django.shortcuts import reverse from django.test import Client, TestCase -from rest_framework.relations import Hyperlink - from access.models.tenant import Tenant as Organization from access.models.team import Team from access.models.team_user import TeamUsers from api.tests.abstract.api_fields import APITenancyObject -from assistance.models.knowledge_base import KnowledgeBase +from assistance.models.knowledge_base import KnowledgeBase, KnowledgeBaseCategory from project_management.models.projects import ProjectState @@ -25,7 +22,9 @@ User = django.contrib.auth.get_user_model() -@pytest.mark.skip( reason = 'to be re-written' ) +@pytest.mark.model_projectstate +@pytest.mark.module_project_management +# @pytest.mark.skip( reason = 'to be re-written' ) class ProjectStateAPI( TestCase, APITenancyObject @@ -45,16 +44,24 @@ class ProjectStateAPI( self.organization = Organization.objects.create(name='test_org') + self.view_user = User.objects.create_user(username="test_user_view", password="password") + kb = KnowledgeBase.objects.create( organization = self.organization, - title = 'kb article' + title = 'kb article', + category = KnowledgeBaseCategory.objects.create( + organization = self.organization, + name = 'kb_cat' + ), + responsible_user = self.view_user, + target_user = self.view_user, ) self.item = ProjectState.objects.create( organization = self.organization, name = 'a state', model_notes = 'note', - # runbook = kb, + runbook = kb, ) @@ -73,8 +80,6 @@ class ProjectStateAPI( view_team.permissions.set([view_permissions]) - self.view_user = User.objects.create_user(username="test_user_view", password="password") - user_settings = UserSettings.objects.get(user = self.view_user) user_settings.default_organization = self.organization diff --git a/app/project_management/tests/unit/project_state/test_unit_project_state_model.py b/app/project_management/tests/unit/project_state/test_unit_project_state_model.py index 67ed6c6d..35482190 100644 --- a/app/project_management/tests/unit/project_state/test_unit_project_state_model.py +++ b/app/project_management/tests/unit/project_state/test_unit_project_state_model.py @@ -1,15 +1,78 @@ -from django.test import TestCase +import pytest -from centurion.tests.unit.test_unit_models import ( - TenancyObjectInheritedCases +from django.db import models + + +from core.tests.unit.centurion_abstract.test_unit_centurion_abstract_model import ( + CenturionAbstractModelInheritedCases ) -from project_management.models.project_states import ProjectState -class ProjectStateModel( - TenancyObjectInheritedCases, - TestCase, +@pytest.mark.model_projectstate +class ProjectStateModelTestCases( + CenturionAbstractModelInheritedCases ): - model = ProjectState + + @property + def parameterized_class_attributes(self): + + return { + 'model_tag': { + 'type': str, + 'value': 'project_state' + }, + } + + + @property + def parameterized_model_fields(self): + + return { + 'name': { + 'blank': False, + 'default': models.fields.NOT_PROVIDED, + 'field_type': models.CharField, + 'length': 100, + 'null': False, + 'unique': True, + }, + 'runbook': { + 'blank': True, + 'default': models.fields.NOT_PROVIDED, + 'field_type': models.ForeignKey, + 'null': True, + 'unique': False, + }, + 'is_completed': { + 'blank': False, + 'default': False, + 'field_type': models.BooleanField, + 'null': False, + 'unique': False, + }, + 'modified': { + 'blank': False, + 'default': models.fields.NOT_PROVIDED, + 'field_type': models.DateTimeField, + 'null': False, + 'unique': False, + }, + } + + + +class ProjectStateModelInheritedCases( + ProjectStateModelTestCases, +): + pass + + + +@pytest.mark.module_project_management +class ProjectStateModelPyTest( + ProjectStateModelTestCases, +): + + pass \ No newline at end of file diff --git a/app/project_management/tests/unit/project_state/test_unit_project_state_viewset.py b/app/project_management/tests/unit/project_state/test_unit_project_state_viewset.py index 46ffcedf..3e3a10c0 100644 --- a/app/project_management/tests/unit/project_state/test_unit_project_state_viewset.py +++ b/app/project_management/tests/unit/project_state/test_unit_project_state_viewset.py @@ -1,3 +1,5 @@ +import pytest + from django.test import Client, TestCase from rest_framework.reverse import reverse @@ -8,6 +10,8 @@ from project_management.viewsets.project_state import ViewSet +@pytest.mark.model_projectstate +@pytest.mark.module_project_management class ProjectStateViewsetList( ModelViewSetInheritedCases, TestCase, diff --git a/app/tests/fixtures/__init__.py b/app/tests/fixtures/__init__.py index 1109cad0..04f5fe3b 100644 --- a/app/tests/fixtures/__init__.py +++ b/app/tests/fixtures/__init__.py @@ -178,6 +178,11 @@ from .model_projectmilestone import ( model_projectmilestone, ) +from .model_projectstate import ( + kwargs_projectstate, + model_projectstate, +) + from .model_service import ( kwargs_service, model_service, diff --git a/app/tests/fixtures/model_projectstate.py b/app/tests/fixtures/model_projectstate.py new file mode 100644 index 00000000..f3fce986 --- /dev/null +++ b/app/tests/fixtures/model_projectstate.py @@ -0,0 +1,29 @@ +import datetime +import pytest + +from project_management.models.project_states import ProjectState + + + +@pytest.fixture( scope = 'class') +def model_projectstate(): + + yield ProjectState + + +@pytest.fixture( scope = 'class') +def kwargs_projectstate(kwargs_centurionmodel): + + random_str = str(datetime.datetime.now(tz=datetime.timezone.utc)) + random_str = str(random_str).replace( + ' ', '').replace(':', '').replace('+', '').replace('.', '') + + kwargs = kwargs_centurionmodel.copy() + del kwargs['model_notes'] + + kwargs = { + **kwargs, + 'name': 'projectstate_' + random_str, + } + + yield kwargs.copy() diff --git a/pyproject.toml b/pyproject.toml index 12253d88..5bed95c3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1096,6 +1096,7 @@ markers = [ "model_port: Selects tests for model port.", "model_project: Selects tests for model Project.", "model_projectmilestone: Selects tests for model Project Milestone.", + "model_projectstate: Selects tests for model Project State.", "model_service: Selects tests for model Service.", "model_software: Selects tests for model Software.", "model_softwarecategory: Selects tests for model Software Category.",