diff --git a/app/project_management/tests/functional/project_milestone/test_project_milestone_serializer.py b/app/project_management/tests/functional/project_milestone/test_project_milestone_serializer.py deleted file mode 100644 index 53b5cff0..00000000 --- a/app/project_management/tests/functional/project_milestone/test_project_milestone_serializer.py +++ /dev/null @@ -1,126 +0,0 @@ -import pytest - -from django.test import TestCase - -from rest_framework.exceptions import ValidationError - -from access.models.tenant import Tenant as Organization - -from project_management.serializers.project_milestone import ( - Project, - ProjectMilestone, - ProjectMilestoneModelSerializer -) - - - -class ProjectMilestoneValidationAPI( - TestCase, -): - - model = ProjectMilestone - - @classmethod - def setUpTestData(self): - """Setup Test - - 1. Create an org - 2. Create an item - """ - - organization = Organization.objects.create(name='test_org') - - self.organization = organization - - self.project = Project.objects.create( - name = 'proj mile', - organization = self.organization - ) - - - - def test_serializer_validation_can_create(self): - """Serializer Validation Check - - Ensure that a valid item can be creates - """ - - # self._kwargs['context']['view'].kwargs['project_id']) - - class MockView: - - kwargs = { - 'project_id': self.project.id - } - - serializer = ProjectMilestoneModelSerializer( - context = { - 'view': MockView - }, - data={ - "organization": self.organization.id, - "name": 'a milestone', - } - ) - - assert serializer.is_valid(raise_exception = True) - - - - def test_serializer_validation_no_name(self): - """Serializer Validation Check - - Ensure that if creating and no name is provided a validation error occurs - """ - - class MockView: - - kwargs = { - 'project_id': self.project.id - } - - with pytest.raises(ValidationError) as err: - - serializer = ProjectMilestoneModelSerializer( - context = { - 'view': MockView - }, - data={ - "organization": self.organization.id, - }, - ) - - serializer.is_valid(raise_exception = True) - - assert err.value.get_codes()['name'][0] == 'required' - - - - # def test_serializer_validation_no_project(self): - # """Serializer Validation Check - - # Ensure that if creating and no name is provided a validation error occurs - # """ - - # class MockView: - - # kwargs = { - # 'project_id': self.project.id - # } - - # with pytest.raises(ValidationError) as err: - - # serializer = ProjectMilestoneModelSerializer( - # context = { - # 'view': MockView - # }, - # data={ - # "organization": self.organization.id, - # "name": 'a milestone', - # }, - # ) - - # serializer.is_valid(raise_exception = True) - - # assert err.value.get_codes()['project'][0] == 'required' - diff --git a/app/project_management/tests/unit/project_milestone/conftest.py b/app/project_management/tests/unit/project_milestone/conftest.py index cc84246d..91a425d8 100644 --- a/app/project_management/tests/unit/project_milestone/conftest.py +++ b/app/project_management/tests/unit/project_milestone/conftest.py @@ -17,3 +17,9 @@ def model_kwargs(request, kwargs_projectmilestone): if hasattr(request.cls, 'kwargs_create_item'): del request.cls.kwargs_create_item + + +@pytest.fixture( scope = 'class') +def model_serializer(serializer_projectmilestone): + + yield serializer_projectmilestone diff --git a/app/project_management/tests/unit/project_milestone/test_unit_project_milestone_serializer.py b/app/project_management/tests/unit/project_milestone/test_unit_project_milestone_serializer.py new file mode 100644 index 00000000..82f1da29 --- /dev/null +++ b/app/project_management/tests/unit/project_milestone/test_unit_project_milestone_serializer.py @@ -0,0 +1,171 @@ +import pytest + +from django.db import models + +from rest_framework.exceptions import ValidationError + +from api.tests.unit.test_unit_serializer import ( + SerializerTestCases +) + +from centurion.tests.abstract.mock_view import MockView +# from project_management.serializers.project import ( +# ProjectMilestone, +# ) + + + +@pytest.mark.model_projectmilestone +class ProjectMilestoneSerializerTestCases( + SerializerTestCases +): + + + # @pytest.fixture( scope = 'function' ) + # def created_model(self, django_db_blocker, model, model_kwargs): + + # with django_db_blocker.unblock(): + + # kwargs_many_to_many = {} + + # kwargs = {} + + # for key, value in model_kwargs.items(): + + # field = model._meta.get_field(key) + + # if isinstance(field, models.ManyToManyField): + + # kwargs_many_to_many.update({ + # key: value + # }) + + # else: + + # kwargs.update({ + # key: value + # }) + + + # item = model.objects.create( **kwargs ) + + # for key, value in kwargs_many_to_many.items(): + + # field = getattr(item, key) + + # for entry in value: + + # field.add(entry) + + # yield item + + # item.delete() + + + + def test_serializer_validation_no_name(self, + kwargs_api_create, model, model_serializer, request_user + ): + """Serializer Validation Check + + Ensure that if creating and no name is provided a validation error occurs + """ + + mock_view = MockView( + user = request_user, + model = model, + action = 'create', + ) + + kwargs = kwargs_api_create.copy() + del kwargs['name'] + + with pytest.raises(ValidationError) as err: + + serializer = model_serializer['model']( + context = { + 'request': mock_view.request, + 'view': mock_view, + }, + data = kwargs, + ) + + serializer.is_valid(raise_exception = True) + + assert err.value.get_codes()['name'][0] == 'required' + + + + def test_serializer_is_valid(self, kwargs_api_create, model, model_serializer, request_user): + """ Serializer Check + + Confirm that using valid data the object validates without exceptions. + """ + + mock_view = MockView( + user = request_user, + model = model, + action = 'create', + ) + + mock_view.kwargs = { 'project_id': kwargs_api_create['project'] } + + serializer = model_serializer['model']( + context = { + 'request': mock_view.request, + 'view': mock_view, + }, + data = kwargs_api_create + ) + + assert serializer.is_valid(raise_exception = True) + + + + @pytest.mark.regression + def test_serializer_create_calls_model_full_clean(self, + kwargs_api_create, mocker, model, model_serializer, request_user + ): + """ Serializer Check + + Confirm that using valid data the object validates without exceptions. + """ + + mock_view = MockView( + user = request_user, + model = model, + action = 'create', + ) + + mock_view.kwargs = { 'project_id': kwargs_api_create['project'] } + + serializer = model_serializer['model']( + context = { + 'request': mock_view.request, + 'view': mock_view, + }, + data = kwargs_api_create + ) + + serializer.is_valid(raise_exception = True) + + full_clean = mocker.spy(model, 'full_clean') + + serializer.save() + + full_clean.assert_called_once() + + + +class ProjectMilestoneSerializerInheritedCases( + ProjectMilestoneSerializerTestCases +): + pass + + + +@pytest.mark.module_project_management +class ProjectMilestoneSerializerPyTest( + ProjectMilestoneSerializerTestCases +): + pass \ No newline at end of file diff --git a/app/tests/fixtures/__init__.py b/app/tests/fixtures/__init__.py index 155b7b03..6da37236 100644 --- a/app/tests/fixtures/__init__.py +++ b/app/tests/fixtures/__init__.py @@ -242,6 +242,7 @@ from .model_project import ( from .model_projectmilestone import ( kwargs_projectmilestone, model_projectmilestone, + serializer_projectmilestone, ) from .model_projectstate import ( diff --git a/app/tests/fixtures/model_project.py b/app/tests/fixtures/model_project.py index bef9988c..026a30ac 100644 --- a/app/tests/fixtures/model_project.py +++ b/app/tests/fixtures/model_project.py @@ -2,6 +2,8 @@ import datetime import pytest import random +from django.db import models + from project_management.models.projects import Project from project_management.serializers.project import ( ProjectBaseSerializer, @@ -66,10 +68,26 @@ def kwargs_project(kwargs_centurionmodel, django_db_blocker, with django_db_blocker.unblock(): - state.delete() - pr_type.delete() - manager.delete() - team_member.delete() + try: + state.delete() + except models.deletion.ProtectedError: + pass + + try: + pr_type.delete() + except models.deletion.ProtectedError: + pass + + try: + manager.delete() + except models.deletion.ProtectedError: + pass + + try: + team_member.delete() + except models.deletion.ProtectedError: + pass + @pytest.fixture( scope = 'class') diff --git a/app/tests/fixtures/model_projectmilestone.py b/app/tests/fixtures/model_projectmilestone.py index ba97f8c8..4fe77234 100644 --- a/app/tests/fixtures/model_projectmilestone.py +++ b/app/tests/fixtures/model_projectmilestone.py @@ -1,7 +1,14 @@ import datetime import pytest +from django.db import models + from project_management.models.project_milestone import ProjectMilestone +from project_management.serializers.project_milestone import ( + ProjectMilestoneBaseSerializer, + ProjectMilestoneModelSerializer, + ProjectMilestoneViewSerializer, +) @@ -22,15 +29,39 @@ def kwargs_projectmilestone(django_db_blocker, with django_db_blocker.unblock(): - kwargs = kwargs_project.copy() + # kwargs = kwargs_project.copy() + + + kwargs_many_to_many = {} + + kwargs = {} + + for key, value in kwargs_project.items(): + + field = model_project._meta.get_field(key) + + if isinstance(field, models.ManyToManyField): + + kwargs_many_to_many.update({ + key: value + }) + + else: + + kwargs.update({ + key: value + }) + kwargs.update({ 'name': 'pm' + random_str }) + del kwargs['code'] project = model_project.objects.create( **kwargs ) + kwargs = kwargs_centurionmodel.copy() del kwargs['model_notes'] @@ -38,6 +69,8 @@ def kwargs_projectmilestone(django_db_blocker, **kwargs, 'name': 'pm_' + random_str, 'project': project, + 'start_date': '2025-08-04T00:00:01Z', + 'finish_date': '2025-08-04T00:00:02Z', } yield kwargs.copy() @@ -45,3 +78,13 @@ def kwargs_projectmilestone(django_db_blocker, # with django_db_blocker.unblock(): # project.delete() # milestone is cascade delete + + +@pytest.fixture( scope = 'class') +def serializer_projectmilestone(): + + yield { + 'base': ProjectMilestoneBaseSerializer, + 'model': ProjectMilestoneModelSerializer, + 'view': ProjectMilestoneViewSerializer + }