Files
igny8/backup-api-standard-v1/tests/test_integration_errors.py
2025-11-16 03:28:25 +00:00

93 lines
4.2 KiB
Python

"""
Integration tests for error scenarios
Tests 400, 401, 403, 404, 429, 500 responses return unified format
"""
from rest_framework import status
from django.test import TestCase
from rest_framework.test import APIClient
from igny8_core.auth.models import User, Account, Plan
from igny8_core.api.tests.test_integration_base import IntegrationTestBase
class ErrorScenariosTestCase(IntegrationTestBase):
"""Integration tests for error scenarios"""
def test_400_bad_request_returns_unified_format(self):
"""Test 400 Bad Request returns unified format"""
# Invalid data
data = {'invalid': 'data'}
response = self.client.post('/api/v1/planner/keywords/', data, format='json')
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
self.assert_unified_response_format(response, expected_success=False)
self.assertIn('error', response.data)
self.assertIn('errors', response.data)
self.assertIn('request_id', response.data)
def test_401_unauthorized_returns_unified_format(self):
"""Test 401 Unauthorized returns unified format"""
# Create unauthenticated client
unauthenticated_client = APIClient()
response = unauthenticated_client.get('/api/v1/planner/keywords/')
self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)
self.assert_unified_response_format(response, expected_success=False)
self.assertIn('error', response.data)
self.assertEqual(response.data['error'], 'Authentication required')
self.assertIn('request_id', response.data)
def test_403_forbidden_returns_unified_format(self):
"""Test 403 Forbidden returns unified format"""
# Create viewer user (limited permissions)
viewer_user = User.objects.create_user(
username='viewer',
email='viewer@test.com',
password='testpass123',
role='viewer',
account=self.account
)
viewer_client = APIClient()
viewer_client.force_authenticate(user=viewer_user)
# Try to access admin-only endpoint (if exists)
# For now, test with a protected endpoint that requires editor+
response = viewer_client.post('/api/v1/planner/keywords/auto_cluster/', {}, format='json')
# May return 400 (validation) or 403 (permission), both should be unified
self.assertIn(response.status_code, [status.HTTP_400_BAD_REQUEST, status.HTTP_403_FORBIDDEN])
self.assert_unified_response_format(response, expected_success=False)
self.assertIn('error', response.data)
self.assertIn('request_id', response.data)
def test_404_not_found_returns_unified_format(self):
"""Test 404 Not Found returns unified format"""
response = self.client.get('/api/v1/planner/keywords/99999/')
self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
self.assert_unified_response_format(response, expected_success=False)
self.assertIn('error', response.data)
self.assertEqual(response.data['error'], 'Resource not found')
self.assertIn('request_id', response.data)
def test_404_invalid_endpoint_returns_unified_format(self):
"""Test 404 for invalid endpoint returns unified format"""
response = self.client.get('/api/v1/nonexistent/endpoint/')
self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
# DRF may return different format for URL not found, but our handler should catch it
if 'success' in response.data:
self.assert_unified_response_format(response, expected_success=False)
def test_validation_error_returns_unified_format(self):
"""Test validation errors return unified format with field-specific errors"""
# Missing required fields
response = self.client.post('/api/v1/planner/keywords/', {}, format='json')
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
self.assert_unified_response_format(response, expected_success=False)
self.assertIn('errors', response.data)
# Should have field-specific errors
self.assertIsInstance(response.data['errors'], dict)