Добавлены тесты для CoreException
This commit is contained in:
@@ -40,7 +40,6 @@ class CoreException(Exception):
|
|||||||
self._process_meta(meta, **kwargs)
|
self._process_meta(meta, **kwargs)
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
# noinspection PyMethodMayBeStatic
|
|
||||||
def is_pure_status(self) -> bool:
|
def is_pure_status(self) -> bool:
|
||||||
"""
|
"""
|
||||||
Возвращает признак необходимости возвращать в ответе реальный статус HTTP
|
Возвращает признак необходимости возвращать в ответе реальный статус HTTP
|
||||||
|
|||||||
@@ -13,4 +13,7 @@ from .core_enum_choices_tests import CoreEnumChoicesTests
|
|||||||
from .core_enum_from_string_tests import CoreEnumFromStringTests
|
from .core_enum_from_string_tests import CoreEnumFromStringTests
|
||||||
from .core_enum_keys_tests import CoreEnumKeysTests
|
from .core_enum_keys_tests import CoreEnumKeysTests
|
||||||
from .core_enum_values_tests import CoreEnumValuesTests
|
from .core_enum_values_tests import CoreEnumValuesTests
|
||||||
|
from .core_exception_is_pure_status_tests import CoreExceptionIsPureStatusTests
|
||||||
|
from .core_exception_process_meta_tests import CoreExceptionProcessMetaTests
|
||||||
|
from .core_exception_tests import CoreExceptionTests
|
||||||
from .core_response_tests import CoreResponseTests
|
from .core_response_tests import CoreResponseTests
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ from ._core_enum_mocks import TestEnum
|
|||||||
|
|
||||||
class CoreEnumCheckIsEmptyTests(CoreSimpleTestCase):
|
class CoreEnumCheckIsEmptyTests(CoreSimpleTestCase):
|
||||||
"""
|
"""
|
||||||
Тестовый класс для метода CoreEnum._check_is_empty()
|
Тестовый класс для CoreEnum._check_is_empty()
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def test_check_is_empty_with_non_empty_enum_does_not_raise_error(self):
|
def test_check_is_empty_with_non_empty_enum_does_not_raise_error(self):
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ from ._core_enum_mocks import TestSingleEnum
|
|||||||
|
|
||||||
class CoreEnumValuesTests(CoreSimpleTestCase):
|
class CoreEnumValuesTests(CoreSimpleTestCase):
|
||||||
"""
|
"""
|
||||||
Тестовый класс CoreEnum.values()
|
Тестовый класс для CoreEnum.values()
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def test_values_returns_list_of_enum_member_values(self):
|
def test_values_returns_list_of_enum_member_values(self):
|
||||||
|
|||||||
@@ -0,0 +1,50 @@
|
|||||||
|
# DRF Rack
|
||||||
|
# Библиотека классов расширений для Django REST Framework
|
||||||
|
#
|
||||||
|
# Автор: Николай В. Анохин <n.anokhin@xeaf.net>
|
||||||
|
# Все права защищены. Лицензия: MIT
|
||||||
|
|
||||||
|
"""
|
||||||
|
Описание класса CoreExceptionIsPureStatusTests
|
||||||
|
"""
|
||||||
|
|
||||||
|
from rest_framework import status
|
||||||
|
|
||||||
|
from net.xeaf.rack.core import CoreException
|
||||||
|
from net.xeaf.rack.core.testing import CoreSimpleTestCase
|
||||||
|
|
||||||
|
|
||||||
|
class CoreExceptionIsPureStatusTests(CoreSimpleTestCase):
|
||||||
|
"""
|
||||||
|
Тестовый класс для CoreException.is_pure_status()
|
||||||
|
"""
|
||||||
|
|
||||||
|
def test_is_pure_status_returns_false_by_default(self):
|
||||||
|
"""
|
||||||
|
Тест проверяет, что по умолчанию is_pure_status возвращает False
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Arrange
|
||||||
|
exception = CoreException(status.HTTP_404_NOT_FOUND)
|
||||||
|
|
||||||
|
# Act
|
||||||
|
result = exception.is_pure_status()
|
||||||
|
|
||||||
|
# Assert
|
||||||
|
self.assertFalse(result)
|
||||||
|
self.assertIsInstance(result, bool)
|
||||||
|
|
||||||
|
def test_is_pure_status_always_returns_false_for_base_exception(self):
|
||||||
|
"""
|
||||||
|
Тест проверяет, что для базового класса исключения метод всегда возвращает False
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Arrange
|
||||||
|
exception1 = CoreException(status.HTTP_400_BAD_REQUEST)
|
||||||
|
exception2 = CoreException(status.HTTP_500_INTERNAL_SERVER_ERROR)
|
||||||
|
exception3 = CoreException(status.HTTP_200_OK)
|
||||||
|
|
||||||
|
# Act & Assert
|
||||||
|
self.assertFalse(exception1.is_pure_status())
|
||||||
|
self.assertFalse(exception2.is_pure_status())
|
||||||
|
self.assertFalse(exception3.is_pure_status())
|
||||||
130
net/xeaf/rack/tests/core/core_exception_process_meta_tests.py
Normal file
130
net/xeaf/rack/tests/core/core_exception_process_meta_tests.py
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
# DRF Rack
|
||||||
|
# Библиотека классов расширений для Django REST Framework
|
||||||
|
#
|
||||||
|
# Автор: Николай В. Анохин <n.anokhin@xeaf.net>
|
||||||
|
# Все права защищены. Лицензия: MIT
|
||||||
|
|
||||||
|
"""
|
||||||
|
Описание класса CoreExceptionProcessMetaTests
|
||||||
|
"""
|
||||||
|
|
||||||
|
from rest_framework import status
|
||||||
|
|
||||||
|
from net.xeaf.rack.core import CoreException
|
||||||
|
from net.xeaf.rack.core.testing import CoreSimpleTestCase
|
||||||
|
|
||||||
|
|
||||||
|
class CoreExceptionProcessMetaTests(CoreSimpleTestCase):
|
||||||
|
"""
|
||||||
|
Тестовый класс для CoreException._process_meta()
|
||||||
|
"""
|
||||||
|
|
||||||
|
def test_process_meta_with_meta_parameter(self):
|
||||||
|
"""
|
||||||
|
Тест проверяет обработку мета-данных при передаче параметра meta
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Arrange
|
||||||
|
exception = CoreException(status.HTTP_400_BAD_REQUEST)
|
||||||
|
meta = {"key": "value", "count": 10}
|
||||||
|
|
||||||
|
# Act
|
||||||
|
exception._process_meta(meta)
|
||||||
|
|
||||||
|
# Assert
|
||||||
|
self.assertEqual(exception.meta, meta)
|
||||||
|
|
||||||
|
def test_process_meta_with_kwargs_only(self):
|
||||||
|
"""
|
||||||
|
Тест проверяет обработку дополнительных параметров при отсутствии meta
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Arrange
|
||||||
|
exception = CoreException(status.HTTP_400_BAD_REQUEST)
|
||||||
|
kwargs = {"param1": "value1", "param2": "value2"}
|
||||||
|
|
||||||
|
# Act
|
||||||
|
exception._process_meta(None, **kwargs)
|
||||||
|
|
||||||
|
# Assert
|
||||||
|
self.assertEqual(exception.meta, kwargs)
|
||||||
|
|
||||||
|
def test_process_meta_with_meta_and_kwargs(self):
|
||||||
|
"""
|
||||||
|
Тест проверяет обработку мета-данных и дополнительных параметров вместе
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Arrange
|
||||||
|
exception = CoreException(status.HTTP_400_BAD_REQUEST)
|
||||||
|
meta = {"existing": "data"}
|
||||||
|
kwargs = {"new": "value", "additional": 123}
|
||||||
|
|
||||||
|
# Act
|
||||||
|
exception._process_meta(meta, **kwargs)
|
||||||
|
|
||||||
|
# Assert
|
||||||
|
self.assertEqual(exception.meta, {"existing": "data", "new": "value", "additional": 123})
|
||||||
|
|
||||||
|
def test_process_meta_with_empty_meta_and_kwargs(self):
|
||||||
|
"""
|
||||||
|
Тест проверяет обработку пустых мета-данных и дополнительных параметров
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Arrange
|
||||||
|
exception = CoreException(status.HTTP_400_BAD_REQUEST)
|
||||||
|
meta = {}
|
||||||
|
kwargs = {"param": "value"}
|
||||||
|
|
||||||
|
# Act
|
||||||
|
exception._process_meta(meta, **kwargs)
|
||||||
|
|
||||||
|
# Assert
|
||||||
|
self.assertEqual(exception.meta, {"param": "value"})
|
||||||
|
|
||||||
|
def test_process_meta_with_meta_none_and_no_kwargs(self):
|
||||||
|
"""
|
||||||
|
Тест проверяет обработку, когда meta равен None и kwargs отсутствуют
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Arrange
|
||||||
|
exception = CoreException(status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
|
# Act
|
||||||
|
exception._process_meta(None)
|
||||||
|
|
||||||
|
# Assert
|
||||||
|
self.assertIsNone(exception.meta)
|
||||||
|
|
||||||
|
def test_process_meta_with_meta_and_kwargs_overwrites_duplicate_keys(self):
|
||||||
|
"""
|
||||||
|
Тест проверяет, что kwargs перезаписывают ключи из meta при совпадении
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Arrange
|
||||||
|
exception = CoreException(status.HTTP_400_BAD_REQUEST)
|
||||||
|
meta = {"key": "from_meta", "keep": "this"}
|
||||||
|
kwargs = {"key": "from_kwargs", "added": "new"}
|
||||||
|
|
||||||
|
# Act
|
||||||
|
exception._process_meta(meta, **kwargs)
|
||||||
|
|
||||||
|
# Assert
|
||||||
|
self.assertEqual(exception.meta, {"key": "from_kwargs", "keep": "this", "added": "new"})
|
||||||
|
|
||||||
|
def test_process_meta_preserves_meta_structure(self):
|
||||||
|
"""
|
||||||
|
Тест проверяет сохранение структуры мета-данных при обновлении
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Arrange
|
||||||
|
exception = CoreException(status.HTTP_400_BAD_REQUEST)
|
||||||
|
meta = {"nested": {"field": "value"}, "list": [1, 2, 3]}
|
||||||
|
kwargs = {"extra": "data"}
|
||||||
|
|
||||||
|
# Act
|
||||||
|
exception._process_meta(meta, **kwargs)
|
||||||
|
|
||||||
|
# Assert
|
||||||
|
self.assertEqual(exception.meta["nested"], {"field": "value"})
|
||||||
|
self.assertEqual(exception.meta["list"], [1, 2, 3])
|
||||||
|
self.assertEqual(exception.meta["extra"], "data")
|
||||||
213
net/xeaf/rack/tests/core/core_exception_tests.py
Normal file
213
net/xeaf/rack/tests/core/core_exception_tests.py
Normal file
@@ -0,0 +1,213 @@
|
|||||||
|
# DRF Rack
|
||||||
|
# Библиотека классов расширений для Django REST Framework
|
||||||
|
#
|
||||||
|
# Автор: Николай В. Анохин <n.anokhin@xeaf.net>
|
||||||
|
# Все права защищены. Лицензия: MIT
|
||||||
|
|
||||||
|
"""
|
||||||
|
Описание класса CoreExceptionTests
|
||||||
|
"""
|
||||||
|
|
||||||
|
from rest_framework import status
|
||||||
|
|
||||||
|
from net.xeaf.rack.core import CoreException
|
||||||
|
from net.xeaf.rack.core.testing import CoreSimpleTestCase
|
||||||
|
|
||||||
|
|
||||||
|
class CoreExceptionTests(CoreSimpleTestCase):
|
||||||
|
"""
|
||||||
|
Тестовый класс для CoreException.__init__()
|
||||||
|
"""
|
||||||
|
|
||||||
|
def test_init_with_required_parameters_only(self):
|
||||||
|
"""
|
||||||
|
Тест проверяет инициализацию исключения только с обязательным параметром status_code
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Arrange
|
||||||
|
status_code = status.HTTP_404_NOT_FOUND
|
||||||
|
|
||||||
|
# Act
|
||||||
|
exception = CoreException(status_code)
|
||||||
|
|
||||||
|
# Assert
|
||||||
|
self.assertEqual(exception.status_code, status_code)
|
||||||
|
self.assertIsNone(exception.detail)
|
||||||
|
self.assertIsNone(exception.meta)
|
||||||
|
self.assertIsInstance(exception, Exception)
|
||||||
|
|
||||||
|
def test_init_with_status_code_and_detail_string(self):
|
||||||
|
"""
|
||||||
|
Тест проверяет инициализацию исключения с кодом статуса и строковым описанием
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Arrange
|
||||||
|
status_code = status.HTTP_400_BAD_REQUEST
|
||||||
|
detail = "Invalid request parameters"
|
||||||
|
|
||||||
|
# Act
|
||||||
|
exception = CoreException(status_code, detail)
|
||||||
|
|
||||||
|
# Assert
|
||||||
|
self.assertEqual(exception.status_code, status_code)
|
||||||
|
self.assertEqual(exception.detail, detail)
|
||||||
|
self.assertIsNone(exception.meta)
|
||||||
|
|
||||||
|
def test_init_with_status_code_and_detail_dict(self):
|
||||||
|
"""
|
||||||
|
Тест проверяет инициализацию исключения с кодом статуса и деталями в виде словаря
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Arrange
|
||||||
|
status_code = status.HTTP_400_BAD_REQUEST
|
||||||
|
detail = {"field": "email", "error": "Invalid email format"}
|
||||||
|
|
||||||
|
# Act
|
||||||
|
exception = CoreException(status_code, detail)
|
||||||
|
|
||||||
|
# Assert
|
||||||
|
self.assertEqual(exception.status_code, status_code)
|
||||||
|
self.assertEqual(exception.detail, detail)
|
||||||
|
self.assertIsNone(exception.meta)
|
||||||
|
|
||||||
|
def test_init_with_status_code_and_detail_list(self):
|
||||||
|
"""
|
||||||
|
Тест проверяет инициализацию исключения с кодом статуса и деталями в виде списка
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Arrange
|
||||||
|
status_code = status.HTTP_400_BAD_REQUEST
|
||||||
|
detail = ["Field 'name' is required", "Field 'email' is required"]
|
||||||
|
|
||||||
|
# Act
|
||||||
|
exception = CoreException(status_code, detail)
|
||||||
|
|
||||||
|
# Assert
|
||||||
|
self.assertEqual(exception.status_code, status_code)
|
||||||
|
self.assertEqual(exception.detail, detail)
|
||||||
|
self.assertIsNone(exception.meta)
|
||||||
|
|
||||||
|
def test_init_with_meta_parameter(self):
|
||||||
|
"""
|
||||||
|
Тест проверяет инициализацию исключения с мета-данными
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Arrange
|
||||||
|
status_code = status.HTTP_403_FORBIDDEN
|
||||||
|
detail = "Access denied"
|
||||||
|
meta = {"resource": "user_profile", "required_permission": "edit"}
|
||||||
|
|
||||||
|
# Act
|
||||||
|
exception = CoreException(status_code, detail, meta)
|
||||||
|
|
||||||
|
# Assert
|
||||||
|
self.assertEqual(exception.status_code, status_code)
|
||||||
|
self.assertEqual(exception.detail, detail)
|
||||||
|
self.assertEqual(exception.meta, meta)
|
||||||
|
|
||||||
|
def test_init_with_empty_meta(self):
|
||||||
|
"""
|
||||||
|
Тест проверяет инициализацию исключения с пустыми мета-данными
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Arrange
|
||||||
|
status_code = status.HTTP_500_INTERNAL_SERVER_ERROR
|
||||||
|
detail = "Internal server error"
|
||||||
|
meta = {}
|
||||||
|
|
||||||
|
# Act
|
||||||
|
exception = CoreException(status_code, detail, meta)
|
||||||
|
|
||||||
|
# Assert
|
||||||
|
self.assertEqual(exception.status_code, status_code)
|
||||||
|
self.assertEqual(exception.detail, detail)
|
||||||
|
self.assertEqual(exception.meta, {})
|
||||||
|
|
||||||
|
def test_init_with_kwargs_only(self):
|
||||||
|
"""
|
||||||
|
Тест проверяет инициализацию исключения с дополнительными параметрами через kwargs
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Arrange
|
||||||
|
status_code = status.HTTP_409_CONFLICT
|
||||||
|
detail = "Conflict"
|
||||||
|
kwargs = {"conflict_id": 123, "conflict_type": "duplicate"}
|
||||||
|
|
||||||
|
# Act
|
||||||
|
exception = CoreException(status_code, detail, **kwargs)
|
||||||
|
|
||||||
|
# Assert
|
||||||
|
self.assertEqual(exception.status_code, status_code)
|
||||||
|
self.assertEqual(exception.detail, detail)
|
||||||
|
self.assertEqual(exception.meta, kwargs)
|
||||||
|
|
||||||
|
def test_init_with_meta_and_kwargs(self):
|
||||||
|
"""
|
||||||
|
Тест проверяет инициализацию исключения с мета-данными и дополнительными параметрами
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Arrange
|
||||||
|
status_code = status.HTTP_429_TOO_MANY_REQUESTS
|
||||||
|
detail = "Too many requests"
|
||||||
|
meta = {"retry_after": 60}
|
||||||
|
kwargs = {"limit": 100, "window": 60}
|
||||||
|
|
||||||
|
# Act
|
||||||
|
exception = CoreException(status_code, detail, meta, **kwargs)
|
||||||
|
|
||||||
|
# Assert
|
||||||
|
self.assertEqual(exception.status_code, status_code)
|
||||||
|
self.assertEqual(exception.detail, detail)
|
||||||
|
self.assertEqual(exception.meta, {"retry_after": 60, "limit": 100, "window": 60})
|
||||||
|
|
||||||
|
def test_init_with_meta_none_and_kwargs(self):
|
||||||
|
"""
|
||||||
|
Тест проверяет инициализацию исключения с None в качестве мета и дополнительными параметрами
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Arrange
|
||||||
|
status_code = status.HTTP_401_UNAUTHORIZED
|
||||||
|
detail = "Unauthorized"
|
||||||
|
kwargs = {"auth_type": "Bearer", "expired": True}
|
||||||
|
|
||||||
|
# Act
|
||||||
|
exception = CoreException(status_code, detail, None, **kwargs)
|
||||||
|
|
||||||
|
# Assert
|
||||||
|
self.assertEqual(exception.status_code, status_code)
|
||||||
|
self.assertEqual(exception.detail, detail)
|
||||||
|
self.assertEqual(exception.meta, kwargs)
|
||||||
|
|
||||||
|
def test_init_with_meta_empty_and_kwargs(self):
|
||||||
|
"""
|
||||||
|
Тест проверяет инициализацию исключения с пустыми мета-данными и дополнительными параметрами
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Arrange
|
||||||
|
status_code = status.HTTP_402_PAYMENT_REQUIRED
|
||||||
|
detail = "Payment required"
|
||||||
|
meta = {}
|
||||||
|
kwargs = {"payment_id": 456, "amount": 99.99}
|
||||||
|
|
||||||
|
# Act
|
||||||
|
exception = CoreException(status_code, detail, meta, **kwargs)
|
||||||
|
|
||||||
|
# Assert
|
||||||
|
self.assertEqual(exception.status_code, status_code)
|
||||||
|
self.assertEqual(exception.detail, detail)
|
||||||
|
self.assertEqual(exception.meta, {"payment_id": 456, "amount": 99.99})
|
||||||
|
|
||||||
|
def test_init_creates_exception_subclass(self):
|
||||||
|
"""
|
||||||
|
Тест проверяет, что CoreException является подклассом Exception
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Arrange
|
||||||
|
status_code = status.HTTP_500_INTERNAL_SERVER_ERROR
|
||||||
|
|
||||||
|
# Act
|
||||||
|
exception = CoreException(status_code)
|
||||||
|
|
||||||
|
# Assert
|
||||||
|
self.assertIsInstance(exception, Exception)
|
||||||
|
self.assertTrue(issubclass(CoreException, Exception))
|
||||||
@@ -17,7 +17,7 @@ from net.xeaf.rack.core.testing import CoreSimpleTestCase
|
|||||||
|
|
||||||
class CoreResponseTests(CoreSimpleTestCase):
|
class CoreResponseTests(CoreSimpleTestCase):
|
||||||
"""
|
"""
|
||||||
Тестовый класс для метода CoreResponse.__init__()
|
Тестовый класс для CoreResponse.__init__()
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def test_init_with_success_status_and_data(self):
|
def test_init_with_success_status_and_data(self):
|
||||||
|
|||||||
Reference in New Issue
Block a user