project initialization
Some checks failed
System Monitoring / Health Checks (push) Has been cancelled
System Monitoring / Performance Monitoring (push) Has been cancelled
System Monitoring / Database Monitoring (push) Has been cancelled
System Monitoring / Cache Monitoring (push) Has been cancelled
System Monitoring / Log Monitoring (push) Has been cancelled
System Monitoring / Resource Monitoring (push) Has been cancelled
System Monitoring / Uptime Monitoring (push) Has been cancelled
System Monitoring / Backup Monitoring (push) Has been cancelled
System Monitoring / Security Monitoring (push) Has been cancelled
System Monitoring / Monitoring Dashboard (push) Has been cancelled
System Monitoring / Alerting (push) Has been cancelled
Security Scanning / Dependency Scanning (push) Has been cancelled
Security Scanning / Code Security Scanning (push) Has been cancelled
Security Scanning / Secrets Scanning (push) Has been cancelled
Security Scanning / Container Security Scanning (push) Has been cancelled
Security Scanning / Compliance Checking (push) Has been cancelled
Security Scanning / Security Dashboard (push) Has been cancelled
Security Scanning / Security Remediation (push) Has been cancelled

This commit is contained in:
2025-10-05 02:37:33 +08:00
parent 2cbb6d5fa1
commit b3fff546e9
226 changed files with 97805 additions and 35 deletions

View File

@@ -0,0 +1,322 @@
"""
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'