feat(core): add core module with mixins, services, and background jobs
- Add Model Mixins: TimestampMixin, SoftDeleteMixin, AuditMixin, etc. - Add Base Services: BaseService, BulkOperationsMixin, QueryOptimizerMixin - Add Base ViewSets with bulk operations - Add BackgroundJob model for Celery task tracking - Add BaseAppCommand for management commands - Add permissions, pagination, filters, cache, logging - Migrate tests to factory_boy + faker - Add CHANGELOG.md - 297 tests passing
This commit is contained in:
152
tests/apps/core/test_exceptions.py
Normal file
152
tests/apps/core/test_exceptions.py
Normal file
@@ -0,0 +1,152 @@
|
||||
"""Tests for core exceptions and exception handler"""
|
||||
|
||||
from apps.core.exceptions import (
|
||||
AuthenticationError,
|
||||
BadRequestError,
|
||||
BaseAPIException,
|
||||
BusinessLogicError,
|
||||
ConflictError,
|
||||
DuplicateError,
|
||||
InternalError,
|
||||
InvalidStateError,
|
||||
NotFoundError,
|
||||
PermissionDeniedError,
|
||||
QuotaExceededError,
|
||||
RateLimitError,
|
||||
ServiceUnavailableError,
|
||||
ValidationError,
|
||||
)
|
||||
from django.test import TestCase
|
||||
|
||||
|
||||
class BaseAPIExceptionTest(TestCase):
|
||||
"""Tests for BaseAPIException"""
|
||||
|
||||
def test_default_values(self):
|
||||
"""Test exception with default values"""
|
||||
exc = BaseAPIException()
|
||||
self.assertEqual(exc.message, "An error occurred")
|
||||
self.assertEqual(exc.code, "error")
|
||||
self.assertEqual(exc.status_code, 400)
|
||||
self.assertIsNone(exc.details)
|
||||
|
||||
def test_custom_values(self):
|
||||
"""Test exception with custom values"""
|
||||
exc = BaseAPIException(
|
||||
message="Custom message",
|
||||
code="custom_code",
|
||||
details={"field": "value"},
|
||||
)
|
||||
self.assertEqual(exc.message, "Custom message")
|
||||
self.assertEqual(exc.code, "custom_code")
|
||||
self.assertEqual(exc.details, {"field": "value"})
|
||||
|
||||
def test_to_dict(self):
|
||||
"""Test conversion to dictionary"""
|
||||
exc = BaseAPIException(
|
||||
message="Test message",
|
||||
code="test_code",
|
||||
details={"key": "value"},
|
||||
)
|
||||
result = exc.to_dict()
|
||||
|
||||
self.assertEqual(result["message"], "Test message")
|
||||
self.assertEqual(result["code"], "test_code")
|
||||
self.assertEqual(result["details"], {"key": "value"})
|
||||
|
||||
def test_to_dict_without_details(self):
|
||||
"""Test to_dict without details"""
|
||||
exc = BaseAPIException(message="Test")
|
||||
result = exc.to_dict()
|
||||
|
||||
self.assertNotIn("details", result)
|
||||
|
||||
|
||||
class ClientErrorExceptionsTest(TestCase):
|
||||
"""Tests for client error exceptions (4xx)"""
|
||||
|
||||
def test_validation_error(self):
|
||||
"""Test ValidationError defaults"""
|
||||
exc = ValidationError()
|
||||
self.assertEqual(exc.status_code, 400)
|
||||
self.assertEqual(exc.code, "validation_error")
|
||||
|
||||
def test_bad_request_error(self):
|
||||
"""Test BadRequestError defaults"""
|
||||
exc = BadRequestError()
|
||||
self.assertEqual(exc.status_code, 400)
|
||||
self.assertEqual(exc.code, "bad_request")
|
||||
|
||||
def test_authentication_error(self):
|
||||
"""Test AuthenticationError defaults"""
|
||||
exc = AuthenticationError()
|
||||
self.assertEqual(exc.status_code, 401)
|
||||
self.assertEqual(exc.code, "authentication_error")
|
||||
|
||||
def test_permission_denied_error(self):
|
||||
"""Test PermissionDeniedError defaults"""
|
||||
exc = PermissionDeniedError()
|
||||
self.assertEqual(exc.status_code, 403)
|
||||
self.assertEqual(exc.code, "permission_denied")
|
||||
|
||||
def test_not_found_error(self):
|
||||
"""Test NotFoundError defaults"""
|
||||
exc = NotFoundError()
|
||||
self.assertEqual(exc.status_code, 404)
|
||||
self.assertEqual(exc.code, "not_found")
|
||||
|
||||
def test_conflict_error(self):
|
||||
"""Test ConflictError defaults"""
|
||||
exc = ConflictError()
|
||||
self.assertEqual(exc.status_code, 409)
|
||||
self.assertEqual(exc.code, "conflict")
|
||||
|
||||
def test_rate_limit_error(self):
|
||||
"""Test RateLimitError defaults"""
|
||||
exc = RateLimitError()
|
||||
self.assertEqual(exc.status_code, 429)
|
||||
self.assertEqual(exc.code, "rate_limit_exceeded")
|
||||
|
||||
|
||||
class ServerErrorExceptionsTest(TestCase):
|
||||
"""Tests for server error exceptions (5xx)"""
|
||||
|
||||
def test_internal_error(self):
|
||||
"""Test InternalError defaults"""
|
||||
exc = InternalError()
|
||||
self.assertEqual(exc.status_code, 500)
|
||||
self.assertEqual(exc.code, "internal_error")
|
||||
|
||||
def test_service_unavailable_error(self):
|
||||
"""Test ServiceUnavailableError defaults"""
|
||||
exc = ServiceUnavailableError()
|
||||
self.assertEqual(exc.status_code, 503)
|
||||
self.assertEqual(exc.code, "service_unavailable")
|
||||
|
||||
|
||||
class BusinessLogicExceptionsTest(TestCase):
|
||||
"""Tests for business logic exceptions"""
|
||||
|
||||
def test_business_logic_error(self):
|
||||
"""Test BusinessLogicError defaults"""
|
||||
exc = BusinessLogicError()
|
||||
self.assertEqual(exc.status_code, 400)
|
||||
self.assertEqual(exc.code, "business_error")
|
||||
|
||||
def test_invalid_state_error(self):
|
||||
"""Test InvalidStateError defaults"""
|
||||
exc = InvalidStateError()
|
||||
self.assertEqual(exc.status_code, 400)
|
||||
self.assertEqual(exc.code, "invalid_state")
|
||||
|
||||
def test_duplicate_error(self):
|
||||
"""Test DuplicateError defaults"""
|
||||
exc = DuplicateError()
|
||||
self.assertEqual(exc.status_code, 409)
|
||||
self.assertEqual(exc.code, "duplicate")
|
||||
|
||||
def test_quota_exceeded_error(self):
|
||||
"""Test QuotaExceededError defaults"""
|
||||
exc = QuotaExceededError()
|
||||
self.assertEqual(exc.status_code, 400)
|
||||
self.assertEqual(exc.code, "quota_exceeded")
|
||||
Reference in New Issue
Block a user