test(core): Refactor TicketBase model API Fields render test Suite to PyTest

ref: #892 #889
This commit is contained in:
2025-07-25 06:42:25 +09:30
parent c7b16874d3
commit bc0180b246
5 changed files with 433 additions and 437 deletions

View File

@ -22,3 +22,11 @@ def create_serializer():
yield ModelSerializer
@pytest.fixture( scope = 'class', autouse = True)
def model_kwargs(request, kwargs_ticketbase):
request.cls.kwargs_create_item = kwargs_ticketbase.copy()
yield kwargs_ticketbase.copy()

View File

@ -0,0 +1,361 @@
import django
import pytest
import random
from django.db import models
from rest_framework.relations import Hyperlink
from api.tests.functional.test_functional_api_fields import (
APIFieldsInheritedCases,
)
@pytest.mark.model_ticketbase
class APITestCases(
APIFieldsInheritedCases,
):
@pytest.fixture( scope = 'class')
def create_model(self, request, django_db_blocker,
model, model_kwargs, model_entity
):
item = None
with django_db_blocker.unblock():
entity_user = model_entity.objects.create(
organization = model_kwargs['organization'],
model_notes = 'asdas'
)
parent_ticket = model.objects.create(
organization = model_kwargs['organization'],
title = 'parent ticket' + str(random.randint(9999,999999)),
description = 'bla bla',
opened_by = model_kwargs['opened_by'],
)
kwargs = model_kwargs.copy()
kwargs['parent_ticket'] = parent_ticket
kwargs['is_solved'] = True
kwargs['date_solved'] = '2025-05-12T02:30:01Z'
kwargs['is_closed'] = True
kwargs['date_closed'] = '2025-05-12T02:30:02Z'
kwargs['status'] = model.TicketStatus.CLOSED
item = model.objects.create(
**kwargs
)
item.assigned_to.add(entity_user)
item.subscribed_to.add(entity_user)
request.cls.item = item
yield item
with django_db_blocker.unblock():
item.delete()
parent_ticket.delete()
entity_user.delete()
@property
def parameterized_api_fields(self):
return {
'model_notes': {
'expected': models.NOT_PROVIDED
},
'_urls.notes': {
'expected': models.NOT_PROVIDED
},
'external_system': {
'expected': int
},
'external_ref': {
'expected': int
},
'parent_ticket': {
'expected': dict
},
'parent_ticket.id': {
'expected': int
},
'parent_ticket.display_name': {
'expected': str
},
'parent_ticket.url': {
'expected': str
},
'ticket_type': {
'expected': str
},
'status': {
'expected': int
},
'status_badge': {
'expected': dict
},
'status_badge.icon': {
'expected': dict
},
'status_badge.icon.name': {
'expected': str
},
'status_badge.icon.style': {
'expected': str
},
'status_badge.text': {
'expected': str
},
'status_badge.text_style': {
'expected': str
},
'status_badge.url': {
'expected': type(None)
},
'category': {
'expected': dict
},
'category.id': {
'expected': int
},
'category.display_name': {
'expected': str
},
'category.url': {
'expected': Hyperlink
},
'title': {
'expected': str
},
'description': {
'expected': str
},
'ticket_duration': {
'expected': int
},
'ticket_estimation': {
'expected': int
},
'project': {
'expected': dict
},
'project.id': {
'expected': int
},
'project.display_name': {
'expected': str
},
'project.url': {
'expected': Hyperlink
},
'milestone': {
'expected': dict
},
'milestone.id': {
'expected': int
},
'milestone.display_name': {
'expected': str
},
'milestone.url': {
'expected': str
},
'urgency': {
'expected': int
},
'urgency_badge': {
'expected': dict
},
'urgency_badge.icon': {
'expected': dict
},
'urgency_badge.icon.name': {
'expected': str
},
'urgency_badge.icon.style': {
'expected': str
},
'urgency_badge.text': {
'expected': str
},
'urgency_badge.text_style': {
'expected': str
},
'urgency_badge.url': {
'expected': type(None)
},
'impact': {
'expected': int
},
'impact_badge': {
'expected': dict
},
'impact_badge.icon': {
'expected': dict
},
'impact_badge.icon.name': {
'expected': str
},
'impact_badge.icon.style': {
'expected': str
},
'impact_badge.text': {
'expected': str
},
'impact_badge.text_style': {
'expected': str
},
'impact_badge.url': {
'expected': type(None)
},
'priority': {
'expected': int
},
'priority_badge': {
'expected': dict
},
'priority_badge.icon': {
'expected': dict
},
'priority_badge.icon.name': {
'expected': str
},
'priority_badge.icon.style': {
'expected': str
},
'priority_badge.text': {
'expected': str
},
'priority_badge.text_style': {
'expected': str
},
'priority_badge.url': {
'expected': type(None)
},
'opened_by': {
'expected': dict
},
'opened_by.id': {
'expected': int
},
'opened_by.display_name': {
'expected': str
},
'opened_by.first_name': {
'expected': str
},
'opened_by.last_name': {
'expected': str
},
'opened_by.username': {
'expected': str
},
'opened_by.username': {
'expected': str
},
'opened_by.is_active': {
'expected': bool
},
'opened_by.url': {
'expected': Hyperlink
},
'subscribed_to': {
'expected': list
},
'subscribed_to.0.id': {
'expected': int
},
'subscribed_to.0.display_name': {
'expected': str
},
'subscribed_to.0.url': {
'expected': str
},
'assigned_to': {
'expected': list
},
'assigned_to.0.id': {
'expected': int
},
'assigned_to.0.display_name': {
'expected': str
},
'assigned_to.0.url': {
'expected': str
},
'planned_start_date': {
'expected': str
},
'planned_finish_date': {
'expected': str
},
'real_start_date': {
'expected': str
},
'real_finish_date': {
'expected': str
},
'is_deleted': {
'expected': bool
},
'is_solved': {
'expected': bool
},
'date_solved': {
'expected': str
},
'is_closed': {
'expected': bool
},
'date_closed': {
'expected': str
},
}
# def test_api_field_value_ticket_type(self):
# """ Test for value of an API Field
# **note:** you must override this test with the correct value for
# your ticket type
# ticket_type field must be 'ticket'
# """
# assert self.api_data['ticket_type'] == 'ticket'
class TicketBaseAPIInheritedCases(
APITestCases,
):
pass
@pytest.mark.module_core
class TicketBaseAPIPyTest(
APITestCases,
):
pass

View File

@ -1,433 +0,0 @@
import django
import pytest
from django.db import models
from rest_framework.relations import Hyperlink
from access.models.entity import Entity
from api.tests.functional.test_functional_api_fields import (
APIFieldsInheritedCases,
)
from core.models.ticket.ticket_category import TicketCategory
from project_management.models.project_milestone import Project, ProjectMilestone
@pytest.mark.model_ticketbase
class APITestCases(
APIFieldsInheritedCases,
):
@pytest.fixture( scope = 'class')
def setup_model(self, request, django_db_blocker,
model,
):
with django_db_blocker.unblock():
request.cls.entity_user = Entity.objects.create(
organization = request.cls.organization,
model_notes = 'asdas'
)
project = Project.objects.create(
organization = request.cls.organization,
name = 'project'
)
parent_ticket = request.cls.model.objects.create(
organization = request.cls.organization,
title = 'parent ticket',
description = 'bla bla',
opened_by = request.cls.view_user,
)
project_milestone = ProjectMilestone.objects.create(
organization = request.cls.organization,
name = 'project milestone one',
project = project
)
request.cls.kwargs_create_item.update({
'category': TicketCategory.objects.create(
organization = request.cls.organization,
name = 'a category'
),
'opened_by': request.cls.view_user,
'project': project,
'milestone': project_milestone,
'parent_ticket': parent_ticket,
'external_system': int(request.cls.model.Ticket_ExternalSystem.CUSTOM_1),
'impact': int(request.cls.model.TicketImpact.MEDIUM),
'priority': int(request.cls.model.TicketPriority.HIGH),
'status': request.cls.model.TicketStatus.CLOSED,
})
if request.cls.model._meta.sub_model_type != 'ticket':
request.cls.url_view_kwargs.update({
'ticket_type': str(request.cls.model._meta.sub_model_type),
})
yield
with django_db_blocker.unblock():
request.cls.entity_user.delete()
parent_ticket.delete()
try:
project_milestone.delete()
except django.db.models.deletion.ProtectedError:
pass
try:
project.delete()
except django.db.models.deletion.ProtectedError:
pass
try:
request.cls.kwargs_create_item['category'].delete()
except django.db.models.deletion.ProtectedError:
pass
if 'ticket_type' in request.cls.url_view_kwargs:
del request.cls.url_view_kwargs['ticket_type']
@pytest.fixture( scope = 'class')
def post_model_create(self, request, django_db_blocker):
with django_db_blocker.unblock():
request.cls.item.assigned_to.add(request.cls.entity_user.id)
request.cls.item.subscribed_to.add(request.cls.entity_user.id)
@pytest.fixture( scope = 'class', autouse = True)
def class_setup(self,
setup_pre,
setup_model,
create_model,
post_model_create,
setup_post,
):
pass
parameterized_test_data = {
'model_notes': {
'expected': models.NOT_PROVIDED
},
'_urls.notes': {
'expected': models.NOT_PROVIDED
},
'external_system': {
'expected': int
},
'external_ref': {
'expected': int
},
'parent_ticket': {
'expected': dict
},
'parent_ticket.id': {
'expected': int
},
'parent_ticket.display_name': {
'expected': str
},
'parent_ticket.url': {
'expected': str
},
'ticket_type': {
'expected': str
},
'status': {
'expected': int
},
'status_badge': {
'expected': dict
},
'status_badge.icon': {
'expected': dict
},
'status_badge.icon.name': {
'expected': str
},
'status_badge.icon.style': {
'expected': str
},
'status_badge.text': {
'expected': str
},
'status_badge.text_style': {
'expected': str
},
'status_badge.url': {
'expected': type(None)
},
'category': {
'expected': dict
},
'category.id': {
'expected': int
},
'category.display_name': {
'expected': str
},
'category.url': {
'expected': Hyperlink
},
'title': {
'expected': str
},
'description': {
'expected': str
},
'ticket_duration': {
'expected': int
},
'ticket_estimation': {
'expected': int
},
'project': {
'expected': dict
},
'project.id': {
'expected': int
},
'project.display_name': {
'expected': str
},
'project.url': {
'expected': Hyperlink
},
'milestone': {
'expected': dict
},
'milestone.id': {
'expected': int
},
'milestone.display_name': {
'expected': str
},
'milestone.url': {
'expected': str
},
'urgency': {
'expected': int
},
'urgency_badge': {
'expected': dict
},
'urgency_badge.icon': {
'expected': dict
},
'urgency_badge.icon.name': {
'expected': str
},
'urgency_badge.icon.style': {
'expected': str
},
'urgency_badge.text': {
'expected': str
},
'urgency_badge.text_style': {
'expected': str
},
'urgency_badge.url': {
'expected': type(None)
},
'impact': {
'expected': int
},
'impact_badge': {
'expected': dict
},
'impact_badge.icon': {
'expected': dict
},
'impact_badge.icon.name': {
'expected': str
},
'impact_badge.icon.style': {
'expected': str
},
'impact_badge.text': {
'expected': str
},
'impact_badge.text_style': {
'expected': str
},
'impact_badge.url': {
'expected': type(None)
},
'priority': {
'expected': int
},
'priority_badge': {
'expected': dict
},
'priority_badge.icon': {
'expected': dict
},
'priority_badge.icon.name': {
'expected': str
},
'priority_badge.icon.style': {
'expected': str
},
'priority_badge.text': {
'expected': str
},
'priority_badge.text_style': {
'expected': str
},
'priority_badge.url': {
'expected': type(None)
},
'opened_by': {
'expected': dict
},
'opened_by.id': {
'expected': int
},
'opened_by.display_name': {
'expected': str
},
'opened_by.first_name': {
'expected': str
},
'opened_by.last_name': {
'expected': str
},
'opened_by.username': {
'expected': str
},
'opened_by.username': {
'expected': str
},
'opened_by.is_active': {
'expected': bool
},
'opened_by.url': {
'expected': Hyperlink
},
'subscribed_to': {
'expected': list
},
'subscribed_to.0.id': {
'expected': int
},
'subscribed_to.0.display_name': {
'expected': str
},
'subscribed_to.0.url': {
'expected': str
},
'assigned_to': {
'expected': list
},
'assigned_to.0.id': {
'expected': int
},
'assigned_to.0.display_name': {
'expected': str
},
'assigned_to.0.url': {
'expected': str
},
'planned_start_date': {
'expected': str
},
'planned_finish_date': {
'expected': str
},
'real_start_date': {
'expected': str
},
'real_finish_date': {
'expected': str
},
'is_deleted': {
'expected': bool
},
'is_solved': {
'expected': bool
},
'date_solved': {
'expected': str
},
'is_closed': {
'expected': bool
},
'date_closed': {
'expected': str
},
}
kwargs_create_item: dict = {
'external_ref': 1,
'title': 'ticket title',
'description': 'the ticket description',
'planned_start_date': '2025-04-16T00:00:01',
'planned_finish_date': '2025-04-16T00:00:02',
'real_start_date': '2025-04-16T00:00:03',
'real_finish_date': '2025-04-16T00:00:04',
'is_solved': True,
'date_solved': '2025-05-12T02:30:01',
'is_closed': True,
'date_closed': '2025-05-12T02:30:02',
}
url_ns_name = '_api_ticketbase'
"""Url namespace (optional, if not required) and url name"""
# def test_api_field_value_ticket_type(self):
# """ Test for value of an API Field
# **note:** you must override this test with the correct value for
# your ticket type
# ticket_type field must be 'ticket'
# """
# assert self.api_data['ticket_type'] == 'ticket'
class TicketBaseAPIInheritedCases(
APITestCases,
):
kwargs_create_item: dict = None
model = None
url_ns_name = '_api_ticketbase_sub'
@pytest.mark.module_core
class TicketBaseAPIPyTest(
APITestCases,
):
pass

View File

@ -464,11 +464,11 @@ class TicketBaseModelTestCases(
' ', '').replace(':', '').replace('+', '').replace('.', '')
kwargs['external_ref'] = int(random_str[len(random_str)-9:])
kwargs['status'] = model._meta.get_field('status').default
ticket = model.objects.create(
**kwargs,
status = model._meta.get_field('status').default,
)
yield ticket

View File

@ -1,5 +1,8 @@
import datetime
import pytest
import random
from django.db import models
from core.models.ticket_base import TicketBase
@ -13,7 +16,9 @@ def model_ticketbase(request):
@pytest.fixture( scope = 'class')
def kwargs_ticketbase(django_db_blocker, kwargs_centurionmodel,
model_user, kwargs_user, model_ticketbase
model_user, kwargs_user, model_ticketbase,
model_project, model_projectmilestone,
model_ticketcategory,
):
random_str = str(datetime.datetime.now(tz=datetime.timezone.utc))
@ -24,16 +29,56 @@ def kwargs_ticketbase(django_db_blocker, kwargs_centurionmodel,
user = model_user.objects.create( **kwargs_user.copy() )
project = model_project.objects.create(
organization = kwargs_centurionmodel['organization'],
name = 'project' + str( random.randint(1, 99999))
)
project_milestone = model_projectmilestone.objects.create(
organization = kwargs_centurionmodel['organization'],
name = 'project milestone one' + str( random.randint(1, 99999)),
project = project
)
category = model_ticketcategory.objects.create(
organization = kwargs_centurionmodel['organization'],
name = 'tb cat ' + str( random.randint(1, 99999)),
)
kwargs = kwargs_centurionmodel.copy()
del kwargs['model_notes']
kwargs = {
**kwargs,
'category': category,
'opened_by': user,
'project': project,
'milestone': project_milestone,
# 'parent_ticket': None,
'external_system': model_ticketbase.Ticket_ExternalSystem.GITHUB,
'external_ref': int(random_str[len(random_str)-9:]),
'impact': int(model_ticketbase.TicketImpact.MEDIUM),
'priority': int(model_ticketbase.TicketPriority.HIGH),
'status': model_ticketbase.TicketStatus.NEW,
'title': 'tb_' + random_str,
'description': 'the body',
'opened_by': user,
'planned_start_date': '2025-04-16T00:00:01Z',
'planned_finish_date': '2025-04-16T00:00:02Z',
'real_start_date': '2025-04-16T00:00:03Z',
'real_finish_date': '2025-04-16T00:00:04Z',
# 'is_solved': True,
# 'date_solved': '2025-05-12T02:30:01',
# 'is_closed': True,
# 'date_closed': '2025-05-12T02:30:02',
}
yield kwargs.copy()
@ -43,4 +88,19 @@ def kwargs_ticketbase(django_db_blocker, kwargs_centurionmodel,
try:
user.delete()
except:
pass
pass
try:
project_milestone.delete()
except models.deletion.ProtectedError:
pass
try:
project.delete()
except models.deletion.ProtectedError:
pass
try:
category.delete()
except models.deletion.ProtectedError:
pass