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:
138
tests/apps/core/test_response.py
Normal file
138
tests/apps/core/test_response.py
Normal file
@@ -0,0 +1,138 @@
|
||||
"""Tests for core response wrapper"""
|
||||
|
||||
from apps.core.response import (
|
||||
api_created_response,
|
||||
api_error_response,
|
||||
api_no_content_response,
|
||||
api_paginated_response,
|
||||
api_response,
|
||||
)
|
||||
from django.test import TestCase
|
||||
from rest_framework import status
|
||||
|
||||
|
||||
class APIResponseTest(TestCase):
|
||||
"""Tests for api_response function"""
|
||||
|
||||
def test_basic_response(self):
|
||||
"""Test basic successful response"""
|
||||
response = api_response({"key": "value"})
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
self.assertTrue(response.data["success"])
|
||||
self.assertEqual(response.data["data"], {"key": "value"})
|
||||
self.assertIsNone(response.data["errors"])
|
||||
|
||||
def test_response_with_request_id(self):
|
||||
"""Test response includes request ID in meta"""
|
||||
response = api_response({"key": "value"}, request_id="test-id-123")
|
||||
|
||||
self.assertEqual(response.data["meta"]["request_id"], "test-id-123")
|
||||
|
||||
def test_response_with_custom_status(self):
|
||||
"""Test response with custom status code"""
|
||||
response = api_response(None, status_code=status.HTTP_202_ACCEPTED)
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED)
|
||||
|
||||
def test_response_with_pagination(self):
|
||||
"""Test response includes pagination in meta"""
|
||||
pagination = {"page": 1, "total": 100}
|
||||
response = api_response([1, 2, 3], pagination=pagination)
|
||||
|
||||
self.assertEqual(response.data["meta"]["pagination"], pagination)
|
||||
|
||||
|
||||
class APIErrorResponseTest(TestCase):
|
||||
"""Tests for api_error_response function"""
|
||||
|
||||
def test_basic_error_response(self):
|
||||
"""Test basic error response"""
|
||||
errors = [{"code": "test_error", "message": "Test error message"}]
|
||||
response = api_error_response(errors)
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
|
||||
self.assertFalse(response.data["success"])
|
||||
self.assertIsNone(response.data["data"])
|
||||
self.assertEqual(response.data["errors"], errors)
|
||||
|
||||
def test_error_response_with_custom_status(self):
|
||||
"""Test error response with custom status code"""
|
||||
errors = [{"code": "not_found", "message": "Not found"}]
|
||||
response = api_error_response(errors, status_code=status.HTTP_404_NOT_FOUND)
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
|
||||
|
||||
def test_error_response_with_request_id(self):
|
||||
"""Test error response includes request ID"""
|
||||
errors = [{"code": "error", "message": "Error"}]
|
||||
response = api_error_response(errors, request_id="error-id-456")
|
||||
|
||||
self.assertEqual(response.data["meta"]["request_id"], "error-id-456")
|
||||
|
||||
|
||||
class APICreatedResponseTest(TestCase):
|
||||
"""Tests for api_created_response function"""
|
||||
|
||||
def test_created_response(self):
|
||||
"""Test 201 created response"""
|
||||
response = api_created_response({"id": 1, "name": "New item"})
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
|
||||
self.assertTrue(response.data["success"])
|
||||
self.assertEqual(response.data["data"]["id"], 1)
|
||||
|
||||
|
||||
class APINoContentResponseTest(TestCase):
|
||||
"""Tests for api_no_content_response function"""
|
||||
|
||||
def test_no_content_response(self):
|
||||
"""Test 204 no content response"""
|
||||
response = api_no_content_response()
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)
|
||||
self.assertTrue(response.data["success"])
|
||||
self.assertIsNone(response.data["data"])
|
||||
|
||||
|
||||
class APIPaginatedResponseTest(TestCase):
|
||||
"""Tests for api_paginated_response function"""
|
||||
|
||||
def test_paginated_response(self):
|
||||
"""Test paginated response with correct metadata"""
|
||||
data = [{"id": 1}, {"id": 2}]
|
||||
response = api_paginated_response(
|
||||
data, page=1, page_size=10, total_count=25
|
||||
)
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
self.assertEqual(response.data["data"], data)
|
||||
|
||||
pagination = response.data["meta"]["pagination"]
|
||||
self.assertEqual(pagination["page"], 1)
|
||||
self.assertEqual(pagination["page_size"], 10)
|
||||
self.assertEqual(pagination["total_count"], 25)
|
||||
self.assertEqual(pagination["total_pages"], 3)
|
||||
self.assertTrue(pagination["has_next"])
|
||||
self.assertFalse(pagination["has_previous"])
|
||||
|
||||
def test_paginated_response_last_page(self):
|
||||
"""Test paginated response on last page"""
|
||||
response = api_paginated_response(
|
||||
[{"id": 1}], page=3, page_size=10, total_count=25
|
||||
)
|
||||
|
||||
pagination = response.data["meta"]["pagination"]
|
||||
self.assertFalse(pagination["has_next"])
|
||||
self.assertTrue(pagination["has_previous"])
|
||||
|
||||
def test_paginated_response_single_page(self):
|
||||
"""Test paginated response with single page"""
|
||||
response = api_paginated_response(
|
||||
[{"id": 1}], page=1, page_size=10, total_count=5
|
||||
)
|
||||
|
||||
pagination = response.data["meta"]["pagination"]
|
||||
self.assertEqual(pagination["total_pages"], 1)
|
||||
self.assertFalse(pagination["has_next"])
|
||||
self.assertFalse(pagination["has_previous"])
|
||||
Reference in New Issue
Block a user