""" Integration test for tenant registration flow. 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 TenantRegistrationIntegrationTest(TestCase): def setUp(self): self.client = APIClient() # Super admin authentication header self.admin_auth = {'HTTP_AUTHORIZATION': 'Bearer super_admin_token'} # Test tenant data self.tenant_data = { 'name': 'Test Healthcare Sdn Bhd', 'email': 'info@testhealthcare.com', 'phone': '+60312345678', 'address': { 'street': '123 Medical Street', 'city': 'Kuala Lumpur', 'state': 'Wilayah Persekutuan', 'postal_code': '50400', 'country': 'Malaysia' }, 'business_type': 'HEALTHCARE', 'subscription_plan': 'GROWTH', 'pricing_model': 'SUBSCRIPTION', 'admin_user': { 'name': 'Dr. Sarah Johnson', 'email': 'sarah.johnson@testhealthcare.com', 'password': 'SecurePassword123!', 'role': 'TENANT_ADMIN', 'phone': '+60123456789' } } def test_complete_tenant_registration_flow(self): """Test complete tenant registration from creation to admin setup.""" # Step 1: Create tenant (should fail before implementation) tenant_response = self.client.post( '/api/v1/tenants/', data=json.dumps(self.tenant_data), content_type='application/json', **self.admin_auth ) assert tenant_response.status_code == status.HTTP_201_CREATED tenant_data = tenant_response.json() # Verify tenant structure assert 'id' in tenant_data assert tenant_data['name'] == self.tenant_data['name'] assert tenant_data['email'] == self.tenant_data['email'] assert tenant_data['business_type'] == self.tenant_data['business_type'] assert tenant_data['status'] == 'PENDING' # Step 2: Verify tenant admin user was created # First, authenticate as super admin to get user list users_response = self.client.get( '/api/v1/users/', **self.admin_auth ) assert users_response.status_code == status.HTTP_200_OK users_data = users_response.json() # Find the newly created admin user admin_user = None for user in users_data['users']: if user['email'] == self.tenant_data['admin_user']['email']: admin_user = user break assert admin_user is not None assert admin_user['name'] == self.tenant_data['admin_user']['name'] assert admin_user['role'] == 'TENANT_ADMIN' assert admin_user['tenant_id'] == tenant_data['id'] # Step 3: Verify subscription was created for tenant subscription_response = self.client.get( '/api/v1/subscriptions/', data={'tenant_id': tenant_data['id']}, **self.admin_auth ) assert subscription_response.status_code == status.HTTP_200_OK subscriptions_data = subscription_response.json() assert len(subscriptions_data['subscriptions']) == 1 subscription = subscriptions_data['subscriptions'][0] assert subscription['tenant_id'] == tenant_data['id'] assert subscription['plan'] == self.tenant_data['subscription_plan'] assert subscription['status'] == 'TRIAL' # Step 4: Test tenant admin authentication # Login as tenant admin login_data = { 'email': self.tenant_data['admin_user']['email'], 'password': self.tenant_data['admin_user']['password'] } auth_response = self.client.post( '/api/v1/auth/login/', data=json.dumps(login_data), content_type='application/json' ) assert auth_response.status_code == status.HTTP_200_OK auth_data = auth_response.json() assert 'access_token' in auth_data assert 'refresh_token' in auth_data assert 'user' in auth_data # Verify user info in token user_info = auth_data['user'] assert user_info['email'] == self.tenant_data['admin_user']['email'] assert user_info['tenant_id'] == tenant_data['id'] # Step 5: Test tenant admin can access their tenant data tenant_admin_auth = {'HTTP_AUTHORIZATION': f'Bearer {auth_data["access_token"]}'} tenant_own_response = self.client.get( '/api/v1/tenants/', **tenant_admin_auth ) assert tenant_own_response.status_code == status.HTTP_200_OK tenant_own_data = tenant_own_response.json() # Should only see their own tenant assert len(tenant_own_data['tenants']) == 1 assert tenant_own_data['tenants'][0]['id'] == tenant_data['id'] # Step 6: Test tenant isolation - cannot see other tenants # Create another tenant as super admin other_tenant_data = self.tenant_data.copy() other_tenant_data['name'] = 'Other Healthcare Sdn Bhd' other_tenant_data['email'] = 'info@otherhealthcare.com' other_tenant_data['admin_user']['email'] = 'admin@otherhealthcare.com' other_tenant_response = self.client.post( '/api/v1/tenants/', data=json.dumps(other_tenant_data), content_type='application/json', **self.admin_auth ) assert other_tenant_response.status_code == status.HTTP_201_CREATED # First tenant admin should still only see their own tenant tenant_still_own_response = self.client.get( '/api/v1/tenants/', **tenant_admin_auth ) assert tenant_still_own_response.status_code == status.HTTP_200_OK tenant_still_own_data = tenant_still_own_response.json() # Should still only see their own tenant assert len(tenant_still_own_data['tenants']) == 1 assert tenant_still_own_data['tenants'][0]['id'] == tenant_data['id'] def test_tenant_registration_invalid_business_type(self): """Test tenant registration with invalid business type.""" invalid_data = self.tenant_data.copy() invalid_data['business_type'] = 'INVALID_TYPE' response = self.client.post( '/api/v1/tenants/', data=json.dumps(invalid_data), content_type='application/json', **self.admin_auth ) assert response.status_code == status.HTTP_400_BAD_REQUEST def test_tenant_registration_missing_admin_user(self): """Test tenant registration without admin user data.""" invalid_data = self.tenant_data.copy() del invalid_data['admin_user'] response = self.client.post( '/api/v1/tenants/', data=json.dumps(invalid_data), content_type='application/json', **self.admin_auth ) assert response.status_code == status.HTTP_400_BAD_REQUEST def test_tenant_registration_duplicate_email(self): """Test tenant registration with duplicate email.""" # Create first tenant first_response = self.client.post( '/api/v1/tenants/', data=json.dumps(self.tenant_data), content_type='application/json', **self.admin_auth ) assert first_response.status_code == status.HTTP_201_CREATED # Try to create second tenant with same email second_response = self.client.post( '/api/v1/tenants/', data=json.dumps(self.tenant_data), content_type='application/json', **self.admin_auth ) assert second_response.status_code == status.HTTP_400_BAD_REQUEST def test_tenant_registration_unauthorized(self): """Test tenant registration without admin authentication.""" response = self.client.post( '/api/v1/tenants/', data=json.dumps(self.tenant_data), content_type='application/json' ) assert response.status_code == status.HTTP_401_UNAUTHORIZED def test_tenant_registration_weak_admin_password(self): """Test tenant registration with weak admin password.""" invalid_data = self.tenant_data.copy() invalid_data['admin_user']['password'] = '123' response = self.client.post( '/api/v1/tenants/', data=json.dumps(invalid_data), content_type='application/json', **self.admin_auth ) assert response.status_code == status.HTTP_400_BAD_REQUEST def test_tenant_registration_with_modules_configuration(self): """Test tenant registration with specific modules configuration.""" modules_data = self.tenant_data.copy() modules_data['modules'] = ['healthcare', 'appointments', 'billing'] modules_data['modules_config'] = { 'healthcare': { 'features': ['patient_management', 'appointment_scheduling', 'medical_records'], 'settings': { 'enable_telemedicine': True, 'appointment_reminders': True } } } response = self.client.post( '/api/v1/tenants/', data=json.dumps(modules_data), content_type='application/json', **self.admin_auth ) if response.status_code == status.HTTP_201_CREATED: tenant_data = response.json() # Should have modules configuration assert 'modules' in tenant_data assert 'modules_config' in tenant_data def test_tenant_registration_with_branding(self): """Test tenant registration with branding information.""" branding_data = self.tenant_data.copy() branding_data['branding'] = { 'logo_url': 'https://example.com/logo.png', 'primary_color': '#2563eb', 'secondary_color': '#64748b', 'company_website': 'https://testhealthcare.com', 'social_media': { 'facebook': 'testhealthcare', 'instagram': 'testhealthcare_my' } } response = self.client.post( '/api/v1/tenants/', data=json.dumps(branding_data), content_type='application/json', **self.admin_auth ) if response.status_code == status.HTTP_201_CREATED: tenant_data = response.json() # Should have branding information assert 'branding' in tenant_data assert tenant_data['branding']['primary_color'] == '#2563eb' def test_tenant_registration_domain_setup(self): """Test tenant registration with custom domain setup.""" domain_data = self.tenant_data.copy() domain_data['domain'] = 'portal.testhealthcare.com' domain_data['settings'] = { 'custom_domain_enabled': True, 'ssl_enabled': True, 'email_domain': 'testhealthcare.com' } response = self.client.post( '/api/v1/tenants/', data=json.dumps(domain_data), content_type='application/json', **self.admin_auth ) if response.status_code == status.HTTP_201_CREATED: tenant_data = response.json() # Should have domain configuration assert 'domain' in tenant_data assert 'settings' in tenant_data assert tenant_data['domain'] == 'portal.testhealthcare.com'