161 lines
6.7 KiB
Python
161 lines
6.7 KiB
Python
"""
|
|
Integration tests for Planner module endpoints
|
|
Tests CRUD operations and AI actions return unified format
|
|
"""
|
|
from rest_framework import status
|
|
from igny8_core.api.tests.test_integration_base import IntegrationTestBase
|
|
from igny8_core.modules.planner.models import Keywords, Clusters, ContentIdeas
|
|
|
|
|
|
class PlannerIntegrationTestCase(IntegrationTestBase):
|
|
"""Integration tests for Planner module"""
|
|
|
|
def test_list_keywords_returns_unified_format(self):
|
|
"""Test GET /api/v1/planner/keywords/ returns unified format"""
|
|
response = self.client.get('/api/v1/planner/keywords/')
|
|
|
|
# May get 429 if rate limited - both should have unified format
|
|
if response.status_code == status.HTTP_429_TOO_MANY_REQUESTS:
|
|
self.assert_unified_response_format(response, expected_success=False)
|
|
else:
|
|
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
|
self.assert_paginated_response(response)
|
|
|
|
def test_create_keyword_returns_unified_format(self):
|
|
"""Test POST /api/v1/planner/keywords/ returns unified format"""
|
|
data = {
|
|
'seed_keyword_id': self.seed_keyword.id,
|
|
'site_id': self.site.id,
|
|
'sector_id': self.sector.id,
|
|
'status': 'active'
|
|
}
|
|
response = self.client.post('/api/v1/planner/keywords/', data, format='json')
|
|
|
|
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
|
|
self.assert_unified_response_format(response, expected_success=True)
|
|
self.assertIn('data', response.data)
|
|
self.assertIn('id', response.data['data'])
|
|
|
|
def test_retrieve_keyword_returns_unified_format(self):
|
|
"""Test GET /api/v1/planner/keywords/{id}/ returns unified format"""
|
|
keyword = Keywords.objects.create(
|
|
seed_keyword=self.seed_keyword,
|
|
site=self.site,
|
|
sector=self.sector,
|
|
account=self.account,
|
|
status='active'
|
|
)
|
|
|
|
response = self.client.get(f'/api/v1/planner/keywords/{keyword.id}/')
|
|
|
|
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
|
self.assert_unified_response_format(response, expected_success=True)
|
|
self.assertIn('data', response.data)
|
|
self.assertEqual(response.data['data']['id'], keyword.id)
|
|
|
|
def test_update_keyword_returns_unified_format(self):
|
|
"""Test PUT /api/v1/planner/keywords/{id}/ returns unified format"""
|
|
keyword = Keywords.objects.create(
|
|
seed_keyword=self.seed_keyword,
|
|
site=self.site,
|
|
sector=self.sector,
|
|
account=self.account,
|
|
status='active'
|
|
)
|
|
|
|
data = {
|
|
'seed_keyword_id': self.seed_keyword.id,
|
|
'site_id': self.site.id,
|
|
'sector_id': self.sector.id,
|
|
'status': 'archived'
|
|
}
|
|
response = self.client.put(f'/api/v1/planner/keywords/{keyword.id}/', data, format='json')
|
|
|
|
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
|
self.assert_unified_response_format(response, expected_success=True)
|
|
self.assertIn('data', response.data)
|
|
|
|
def test_delete_keyword_returns_unified_format(self):
|
|
"""Test DELETE /api/v1/planner/keywords/{id}/ returns unified format"""
|
|
keyword = Keywords.objects.create(
|
|
seed_keyword=self.seed_keyword,
|
|
site=self.site,
|
|
sector=self.sector,
|
|
account=self.account,
|
|
status='active'
|
|
)
|
|
|
|
response = self.client.delete(f'/api/v1/planner/keywords/{keyword.id}/')
|
|
|
|
self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)
|
|
|
|
def test_list_clusters_returns_unified_format(self):
|
|
"""Test GET /api/v1/planner/clusters/ returns unified format"""
|
|
response = self.client.get('/api/v1/planner/clusters/')
|
|
|
|
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
|
self.assert_paginated_response(response)
|
|
|
|
def test_create_cluster_returns_unified_format(self):
|
|
"""Test POST /api/v1/planner/clusters/ returns unified format"""
|
|
data = {
|
|
'name': 'Test Cluster',
|
|
'description': 'Test description',
|
|
'site_id': self.site.id,
|
|
'sector_id': self.sector.id,
|
|
'status': 'active'
|
|
}
|
|
response = self.client.post('/api/v1/planner/clusters/', data, format='json')
|
|
|
|
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
|
|
self.assert_unified_response_format(response, expected_success=True)
|
|
self.assertIn('data', response.data)
|
|
|
|
def test_list_ideas_returns_unified_format(self):
|
|
"""Test GET /api/v1/planner/ideas/ returns unified format"""
|
|
response = self.client.get('/api/v1/planner/ideas/')
|
|
|
|
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
|
self.assert_paginated_response(response)
|
|
|
|
def test_auto_cluster_returns_unified_format(self):
|
|
"""Test POST /api/v1/planner/keywords/auto_cluster/ returns unified format"""
|
|
keyword = Keywords.objects.create(
|
|
seed_keyword=self.seed_keyword,
|
|
site=self.site,
|
|
sector=self.sector,
|
|
account=self.account,
|
|
status='active'
|
|
)
|
|
|
|
data = {
|
|
'ids': [keyword.id],
|
|
'sector_id': self.sector.id
|
|
}
|
|
response = self.client.post('/api/v1/planner/keywords/auto_cluster/', data, format='json')
|
|
|
|
# Should return either task_id (async) or success response
|
|
self.assertIn(response.status_code, [status.HTTP_200_OK, status.HTTP_202_ACCEPTED])
|
|
self.assert_unified_response_format(response, expected_success=True)
|
|
|
|
def test_keyword_validation_error_returns_unified_format(self):
|
|
"""Test validation errors return unified format"""
|
|
# 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('error', response.data)
|
|
self.assertIn('errors', response.data)
|
|
self.assertIn('request_id', response.data)
|
|
|
|
def test_keyword_not_found_returns_unified_format(self):
|
|
"""Test 404 errors return 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.assertIn('request_id', response.data)
|
|
|