Добавлен класс CoreException
This commit is contained in:
@@ -9,4 +9,5 @@
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
from .core_enum import CoreEnum
|
from .core_enum import CoreEnum
|
||||||
|
from .core_exception import CoreException
|
||||||
from .core_test_case import CoreTestCase
|
from .core_test_case import CoreTestCase
|
||||||
|
|||||||
59
net/xeaf/rack/core/core_exception.py
Normal file
59
net/xeaf/rack/core/core_exception.py
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
# DRF Rack
|
||||||
|
# Библиотека классов расширений для Django REST Framework
|
||||||
|
#
|
||||||
|
# Автор: Николай В. Анохин <n.anokhin@xeaf.net>
|
||||||
|
# Все права защищены. Лицензия: MIT
|
||||||
|
|
||||||
|
"""
|
||||||
|
Описание класса CoreException
|
||||||
|
"""
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
|
||||||
|
class CoreException(Exception):
|
||||||
|
"""
|
||||||
|
Реализует базовый функционал всех классов исключений проекта
|
||||||
|
"""
|
||||||
|
|
||||||
|
status_code: int
|
||||||
|
""" Код состояния ответа API """
|
||||||
|
|
||||||
|
detail: str | dict | list | None = None
|
||||||
|
""" Информация об ошибке """
|
||||||
|
|
||||||
|
meta: dict | None = None
|
||||||
|
""" Информация для обработки ошибки """
|
||||||
|
|
||||||
|
def __init__(self, status_code: int, detail: str | dict | list | None = None, meta: dict | None = None, **kwargs: Any):
|
||||||
|
"""
|
||||||
|
Инициализация
|
||||||
|
|
||||||
|
:param status_code: Код состояния ответа API
|
||||||
|
:param detail: Информация об ошибке
|
||||||
|
:param meta: Информация для обработки ошибки
|
||||||
|
:param kwargs: Дополнительные параметры
|
||||||
|
"""
|
||||||
|
|
||||||
|
self.status_code = status_code
|
||||||
|
self.detail = detail
|
||||||
|
self._process_meta(meta, **kwargs)
|
||||||
|
super().__init__()
|
||||||
|
|
||||||
|
def _process_meta(self, meta: dict | None, **kwargs: Any) -> None:
|
||||||
|
"""
|
||||||
|
Разбирает переданные параметры
|
||||||
|
|
||||||
|
:param meta: Метаданные
|
||||||
|
:param kwargs: Дополнительные аргументы
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Метаданные
|
||||||
|
if meta is not None:
|
||||||
|
self.meta = meta
|
||||||
|
elif kwargs:
|
||||||
|
self.meta = {}
|
||||||
|
|
||||||
|
# Дополнительные параметры
|
||||||
|
if kwargs and self.meta is not None:
|
||||||
|
self.meta.update(kwargs)
|
||||||
@@ -9,4 +9,4 @@
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
from .core_enum_tests import CoreEnumTests
|
from .core_enum_tests import CoreEnumTests
|
||||||
|
from .core_exception_tests import CoreExceptionTests
|
||||||
|
|||||||
133
net/xeaf/rack/tests/core/core_exception_tests.py
Normal file
133
net/xeaf/rack/tests/core/core_exception_tests.py
Normal file
@@ -0,0 +1,133 @@
|
|||||||
|
# DRF Rack
|
||||||
|
# Библиотека классов расширений для Django REST Framework
|
||||||
|
#
|
||||||
|
# Автор: Николай В. Анохин <n.anokhin@xeaf.net>
|
||||||
|
# Все права защищены. Лицензия: MIT
|
||||||
|
|
||||||
|
"""
|
||||||
|
Описание класса CoreExceptionTests
|
||||||
|
"""
|
||||||
|
|
||||||
|
from django.test import SimpleTestCase
|
||||||
|
from rest_framework import status
|
||||||
|
|
||||||
|
from net.xeaf.rack.core import CoreException
|
||||||
|
|
||||||
|
|
||||||
|
class CoreExceptionTests(SimpleTestCase):
|
||||||
|
"""
|
||||||
|
Тесты для класса CoreException
|
||||||
|
"""
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
"""
|
||||||
|
Заполняем параметры для теста
|
||||||
|
"""
|
||||||
|
|
||||||
|
self.default_status = status.HTTP_400_BAD_REQUEST
|
||||||
|
self.default_detail = "Тестовая ошибка"
|
||||||
|
self.exc_instance = CoreException(status_code=self.default_status)
|
||||||
|
|
||||||
|
def test_init_with_basic_params(self):
|
||||||
|
"""
|
||||||
|
Проверяет базовую инициализацию без метаданных
|
||||||
|
"""
|
||||||
|
|
||||||
|
exc = CoreException(status_code=self.default_status, detail=self.default_detail)
|
||||||
|
|
||||||
|
self.assertEqual(exc.status_code, self.default_status)
|
||||||
|
self.assertEqual(exc.detail, self.default_detail)
|
||||||
|
self.assertIsNone(exc.meta)
|
||||||
|
|
||||||
|
def test_init_with_meta_only(self):
|
||||||
|
"""
|
||||||
|
Проверяет инициализацию, когда передан только словарь meta
|
||||||
|
"""
|
||||||
|
|
||||||
|
meta_data = {"action": "REDIRECT", "url": "/login/"}
|
||||||
|
|
||||||
|
exc = CoreException(status_code=self.default_status, meta=meta_data)
|
||||||
|
|
||||||
|
self.assertEqual(exc.status_code, self.default_status)
|
||||||
|
self.assertEqual(exc.meta, meta_data)
|
||||||
|
self.assertIsInstance(exc.meta, dict)
|
||||||
|
self.assertEqual(exc.meta["action"], "REDIRECT")
|
||||||
|
|
||||||
|
def test_init_with_kwargs_only(self):
|
||||||
|
"""
|
||||||
|
Проверяет инициализацию, когда meta=None, но переданы именованные аргументы (kwargs)
|
||||||
|
"""
|
||||||
|
|
||||||
|
exc = CoreException(status_code=self.default_status, foo="bar", code=123)
|
||||||
|
|
||||||
|
self.assertEqual(exc.status_code, self.default_status)
|
||||||
|
self.assertIsNotNone(exc.meta)
|
||||||
|
self.assertIsInstance(exc.meta, dict)
|
||||||
|
self.assertEqual(exc.meta["foo"], "bar")
|
||||||
|
self.assertEqual(exc.meta["code"], 123)
|
||||||
|
|
||||||
|
def test_process_meta_with_none(self):
|
||||||
|
"""
|
||||||
|
Если meta=None и kwargs пусты, self.meta должен остаться None
|
||||||
|
"""
|
||||||
|
|
||||||
|
self.exc_instance.meta = None # Сбрасываем состояние перед проверкой
|
||||||
|
|
||||||
|
self.exc_instance._process_meta(meta=None)
|
||||||
|
|
||||||
|
self.assertIsNone(self.exc_instance.meta)
|
||||||
|
|
||||||
|
def test_process_meta_with_dict(self):
|
||||||
|
"""
|
||||||
|
Если передан только словарь meta, он должен записаться в self.meta
|
||||||
|
"""
|
||||||
|
|
||||||
|
self.exc_instance.meta = None
|
||||||
|
test_meta = {"source": "auth_service"}
|
||||||
|
|
||||||
|
self.exc_instance._process_meta(meta=test_meta)
|
||||||
|
|
||||||
|
self.assertEqual(self.exc_instance.meta, test_meta)
|
||||||
|
|
||||||
|
def test_process_meta_with_kwargs_only(self):
|
||||||
|
"""
|
||||||
|
Если meta=None, но есть kwargs, должен создаться словарь с этими kwargs
|
||||||
|
"""
|
||||||
|
|
||||||
|
self.exc_instance.meta = None
|
||||||
|
|
||||||
|
self.exc_instance._process_meta(meta=None, request_id="req_123", user_id=99)
|
||||||
|
|
||||||
|
self.assertIsNotNone(self.exc_instance.meta)
|
||||||
|
self.assertIsInstance(self.exc_instance.meta, dict)
|
||||||
|
self.assertEqual(self.exc_instance.meta["request_id"], "req_123")
|
||||||
|
self.assertEqual(self.exc_instance.meta["user_id"], 99)
|
||||||
|
|
||||||
|
def test_process_meta_combined(self):
|
||||||
|
"""
|
||||||
|
Если переданы и meta, и kwargs, они должны успешно объединиться (update)
|
||||||
|
"""
|
||||||
|
|
||||||
|
self.exc_instance.meta = None
|
||||||
|
initial_meta = {"version": "v1"}
|
||||||
|
|
||||||
|
self.exc_instance._process_meta(meta=initial_meta, debug=True, env="prod")
|
||||||
|
|
||||||
|
self.assertIsNotNone(self.exc_instance.meta)
|
||||||
|
self.assertIsInstance(self.exc_instance.meta, dict)
|
||||||
|
self.assertEqual(self.exc_instance.meta["version"], "v1")
|
||||||
|
self.assertEqual(self.exc_instance.meta["debug"], True)
|
||||||
|
self.assertEqual(self.exc_instance.meta["env"], "prod")
|
||||||
|
|
||||||
|
def test_process_meta_with_empty_dict_and_kwargs(self):
|
||||||
|
"""
|
||||||
|
Критический случай: meta пришел пустым словарем, но kwargs заполнены
|
||||||
|
"""
|
||||||
|
|
||||||
|
self.exc_instance.meta = None
|
||||||
|
|
||||||
|
self.exc_instance._process_meta(meta={}, trace_id="xyz")
|
||||||
|
|
||||||
|
self.assertIsNotNone(self.exc_instance.meta)
|
||||||
|
self.assertIsInstance(self.exc_instance.meta, dict)
|
||||||
|
self.assertEqual(self.exc_instance.meta["trace_id"], "xyz")
|
||||||
@@ -14,7 +14,7 @@ from net.xeaf.rack.managers import CryptoManager
|
|||||||
|
|
||||||
class CryptoManagerTests(CoreTestCase):
|
class CryptoManagerTests(CoreTestCase):
|
||||||
"""
|
"""
|
||||||
Тесты для класса Crypto
|
Тесты для класса CryptoManager
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def test_gen_token(self):
|
def test_gen_token(self):
|
||||||
|
|||||||
Reference in New Issue
Block a user