""" Contract test for GET /modules endpoint. This test MUST fail before implementation. """ import pytest from django.test import TestCase from django.urls import reverse from rest_framework.test import APIClient from rest_framework import status import json class ModulesGetContractTest(TestCase): def setUp(self): self.client = APIClient() self.modules_url = '/api/v1/modules/' # Admin authentication header self.admin_auth = {'HTTP_AUTHORIZATION': 'Bearer admin_token'} # Tenant admin authentication header self.tenant_admin_auth = {'HTTP_AUTHORIZATION': 'Bearer tenant_admin_token'} def test_get_modules_success_admin(self): """Test successful retrieval of modules list by admin.""" response = self.client.get( self.modules_url, **self.admin_auth ) # This should fail before implementation assert response.status_code == status.HTTP_200_OK data = response.json() assert 'modules' in data assert isinstance(data['modules'], list) # Should return all available modules expected_modules = ['retail', 'healthcare', 'education', 'logistics', 'beauty'] returned_modules = [module['key'] for module in data['modules']] for expected_module in expected_modules: assert expected_module in returned_modules def test_get_modules_success_tenant_admin(self): """Test successful retrieval of modules list by tenant admin.""" response = self.client.get( self.modules_url, **self.tenant_admin_auth ) # This should fail before implementation assert response.status_code == status.HTTP_200_OK data = response.json() assert 'modules' in data assert isinstance(data['modules'], list) # Tenant admin should see modules available to their subscription # This will be validated once implementation exists def test_get_modules_unauthorized(self): """Test modules list retrieval without authentication.""" response = self.client.get(self.modules_url) assert response.status_code == status.HTTP_401_UNAUTHORIZED def test_get_modules_filter_by_category(self): """Test modules list retrieval filtered by category.""" params = { 'category': 'core' } response = self.client.get( self.modules_url, data=params, **self.admin_auth ) assert response.status_code == status.HTTP_200_OK data = response.json() # All returned modules should have the specified category for module in data['modules']: assert module['category'] == 'core' def test_get_modules_filter_by_status(self): """Test modules list retrieval filtered by status.""" params = { 'status': 'ACTIVE' } response = self.client.get( self.modules_url, data=params, **self.admin_auth ) assert response.status_code == status.HTTP_200_OK data = response.json() # All returned modules should have the specified status for module in data['modules']: assert module['status'] == 'ACTIVE' def test_get_modules_filter_by_tenant(self): """Test modules list retrieval filtered by tenant subscription.""" params = { 'tenant_id': 'test-tenant-id', 'only_subscribed': 'true' } response = self.client.get( self.modules_url, data=params, **self.admin_auth ) assert response.status_code == status.HTTP_200_OK data = response.json() # All returned modules should be subscribed by the tenant # This will be validated once implementation exists def test_get_modules_with_details(self): """Test modules list retrieval with detailed information.""" params = { 'include_details': 'true' } response = self.client.get( self.modules_url, data=params, **self.admin_auth ) assert response.status_code == status.HTTP_200_OK data = response.json() if len(data['modules']) > 0: module = data['modules'][0] # Should include detailed information assert 'description' in module assert 'features' in module assert 'pricing' in module assert 'requirements' in module # Features should be a list assert isinstance(module['features'], list) # Pricing should include relevant information pricing = module['pricing'] assert 'base_price' in pricing assert 'currency' in pricing assert 'billing_cycle' in pricing def test_get_modules_tenant_specific_view(self): """Test that tenant admin sees modules available to their subscription.""" response = self.client.get( self.modules_url, **self.tenant_admin_auth ) if response.status_code == status.HTTP_200_OK: data = response.json() # Tenant admin should see which modules are available and which are subscribed # This will be validated once implementation exists pass def test_get_modules_data_structure(self): """Test that module data structure matches the contract.""" response = self.client.get( self.modules_url, **self.admin_auth ) if response.status_code == status.HTTP_200_OK and len(response.json()['modules']) > 0: module = response.json()['modules'][0] # Required fields according to contract required_fields = [ 'id', 'key', 'name', 'category', 'status', 'version', 'created_at', 'updated_at' ] for field in required_fields: assert field in module # Field types and enums assert isinstance(module['id'], str) assert isinstance(module['key'], str) assert isinstance(module['name'], str) assert module['category'] in ['core', 'industry', 'integration'] assert module['status'] in ['ACTIVE', 'INACTIVE', 'DEPRECATED'] assert isinstance(module['version'], str) def test_get_modules_with_compatibility_info(self): """Test that module data includes compatibility information.""" response = self.client.get( self.modules_url, data={'include_compatibility': 'true'}, **self.admin_auth ) if response.status_code == status.HTTP_200_OK and len(response.json()['modules']) > 0: module = response.json()['modules'][0] # Should include compatibility information assert 'compatibility' in module compatibility = module['compatibility'] # Compatibility should include relevant fields expected_compatibility_fields = ['min_platform_version', 'required_modules', 'conflicts'] for field in expected_compatibility_fields: assert field in compatibility def test_get_modules_with_usage_stats(self): """Test that module data includes usage statistics for admin.""" response = self.client.get( self.modules_url, data={'include_stats': 'true'}, **self.admin_auth ) if response.status_code == status.HTTP_200_OK and len(response.json()['modules']) > 0: module = response.json()['modules'][0] # Should include usage statistics assert 'usage_stats' in module stats = module['usage_stats'] # Stats should include relevant fields expected_stats_fields = ['active_tenants', 'total_users', 'api_calls_today', 'storage_used'] for field in expected_stats_fields: assert field in stats def test_get_modules_search(self): """Test modules list retrieval with search functionality.""" params = { 'search': 'retail' } response = self.client.get( self.modules_url, data=params, **self.admin_auth ) assert response.status_code == status.HTTP_200_OK data = response.json() # All returned modules should match search criteria for module in data['modules']: search_match = ( 'retail' in module['name'].lower() or 'retail' in module['key'].lower() or 'retail' in module['description'].lower() ) assert search_match def test_get_modules_sorting(self): """Test modules list retrieval with sorting.""" params = { 'sort_by': 'name', 'sort_order': 'asc' } response = self.client.get( self.modules_url, data=params, **self.admin_auth ) assert response.status_code == status.HTTP_200_OK data = response.json() # Modules should be sorted by name in ascending order module_names = [module['name'] for module in data['modules']] assert module_names == sorted(module_names)